求助:实现将SQL表列头转成行、NDC值转为列头的查询
解决SQL行列转置问题
要实现你需要的转置效果,得结合Unpivot和Pivot两步操作,下面分静态和动态场景给出方案:
静态场景(NDC值固定为1、2、3)
假设原表名为Table1,执行以下SQL即可得到目标结果:
SELECT Attribute, [1], [2], [3] FROM ( -- 第一步:Unpivot,把原表的列转成Attribute-Value行 SELECT Attribute, NDC, Value FROM Table1 UNPIVOT ( Value FOR Attribute IN (NDC, Address, Customer) ) AS Unpivoted ) AS PivotSource -- 第二步:Pivot,把NDC值转成列,按Attribute分组取对应值 PIVOT ( MAX(Value) FOR NDC IN ([1], [2], [3]) ) AS PivotedResult;
执行逻辑说明
Unpivot阶段:将原表每一行拆分为3行,每行对应原表的一个列名(Attribute)、NDC标识和对应值(Value),输出结构如下:
Attribute NDC Value NDC 1 1 Address 1 100 Customer 1 Bobs NDC 2 2 ... ... ... Pivot阶段:以
Attribute为分组依据,把不同的NDC值转成列,用MAX(Value)聚合(因为每个Attribute+NDC组合唯一,MAX不影响结果),最终得到你要的行列转置结果。
动态场景(NDC值不固定,可能新增)
如果NDC的值是动态变化的,静态SQL无法适配,需要用动态SQL自动生成列名:
DECLARE @cols NVARCHAR(MAX), @query NVARCHAR(MAX); -- 自动获取所有唯一NDC值,格式化为带引号的列名 SELECT @cols = STRING_AGG(QUOTENAME(NDC), ', ') FROM (SELECT DISTINCT NDC FROM Table1) AS NDCList; -- 构建动态查询语句 SET @query = ' SELECT Attribute, ' + @cols + ' FROM ( SELECT Attribute, NDC, Value FROM Table1 UNPIVOT ( Value FOR Attribute IN (NDC, Address, Customer) ) AS Unpivoted ) AS PivotSource PIVOT ( MAX(Value) FOR NDC IN (' + @cols + ') ) AS PivotedResult; '; -- 执行动态SQL EXEC sp_executesql @query;
常见问题排查
你之前尝试Pivot/Unpivot失败,大概率是以下原因:
- Unpivot时没包含
NDC列,导致后续无法用NDC作为Pivot的列依据 - Pivot的分组字段错误,没有以原表的列名(转成Attribute后)作为分组键
内容的提问来源于stack exchange,提问作者Jeff
相关产品推荐
相关产品推荐

