SQL Server 2016 动态行数场景下表行转列的实现方案咨询
SQL Server 2016 动态行转列实现方案
完全可以实现,你的场景需要先对原表的信用等级列做逆透视转换,再根据动态的strategy值做透视,SQL Server 2016 支持动态PIVOT语法适配行数动态变化的需求。
1. 静态实现(仅用于逻辑验证,适配strategy固定的场景)
先通过静态写法理解核心逻辑:
SELECT year, month, [Credit Type], [InvestmentA], [InvestmentB], [Investment(n)] FROM ( -- 第一步:逆透视,将aaa/aa/a等列转为行,生成Credit Type字段 SELECT strategy, year, month, [Credit Type], val FROM Characteristics UNPIVOT ( val FOR [Credit Type] IN (aaa, aa, a) ) AS unpvt ) AS src -- 第二步:透视,将strategy的不同值转为列 PIVOT ( -- 每个组合仅对应一个值,聚合函数用MAX/MIN/SUM均可 MAX(val) FOR strategy IN ([InvestmentA], [InvestmentB], [Investment(n)]) ) AS pvt
2. 动态实现(适配strategy行数动态变化的生产场景)
当strategy的取值动态新增时,通过动态SQL拼接需要透视的列即可:
DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX) -- 拼接所有去重后的strategy列名,自动适配新增的strategy值 SELECT @cols = STUFF((SELECT ',' + QUOTENAME(strategy) FROM Characteristics GROUP BY strategy ORDER BY strategy FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'') -- 拼接完整执行语句 SET @query = N'SELECT year, month, [Credit Type], ' + @cols + N' FROM ( SELECT strategy, year, month, [Credit Type], val FROM Characteristics UNPIVOT ( val FOR [Credit Type] IN (aaa, aa, a) ) AS unpvt ) AS src PIVOT ( MAX(val) FOR strategy IN (' + @cols + N') ) AS pvt' -- 执行动态SQL,输出最终结果 EXEC sp_executesql @query
注意事项
- 如果信用类型(aaa/aa/a等字段)也会动态新增,可参考拼接
@cols的逻辑,查询系统表获取信用类型相关列名,替换UNPIVOT部分的固定列即可。 - 调试时可先执行
PRINT @query输出生成的完整SQL语句,验证逻辑是否符合预期。
内容的提问来源于stack exchange,提问作者MikeMcD
相关产品推荐
相关产品推荐

