SQL行列转换需求:将Pair Row数据转为指定列格式(非单行Pivot)
搞定按Order分组的行转列需求
嘿,我明白你要做的事儿了——把原来分散在多行里的COLID数据,转换成按Order分组、每个COLID单独占一列的格式,而且不是常规Pivot那种把所有数据揉成一行,而是每个Order对应一行,对吧?
核心思路
这里确实用PIVOT就能解决,但关键是要把**Order(还有SetID)作为分组依据**,而不是把SetID当成唯一分组键。因为每个(SetID, COLID, Order)的组合都是唯一的,所以聚合函数用MAX或者MIN都不会有问题,只是用来提取那个唯一的DataValue而已。
硬编码列的示例(适合COLID固定的情况)
先建个临时表放你的示例数据:
CREATE TABLE #TempData ( SetID INT, COLID INT, DataValue VARCHAR(50), [Order] INT ); INSERT INTO #TempData VALUES (1,1,'Value1',1), (1,1,'Value2',2), (1,1,'Value3',3), (1,2,'Value4',1), (1,2,'Value5',2), (1,2,'Value6',3);
然后用Pivot查询得到你要的结果:
SELECT SetID, [1] AS COL1_Value, -- [1]对应COLID=1的列 [2] AS COL2_Value, -- [2]对应COLID=2的列 [Order] FROM #TempData PIVOT ( MAX(DataValue) -- 因为每个分组只有一个值,MAX/MIN都可 FOR COLID IN ([1], [2]) ) AS PivotedData ORDER BY [Order];
执行后得到的结果完全匹配你的需求:
| SetID | COL1_Value | COL2_Value | Order |
|---|---|---|---|
| 1 | Value1 | Value4 | 1 |
| 1 | Value2 | Value5 | 2 |
| 1 | Value3 | Value6 | 3 |
动态列的示例(适合COLID不固定的情况)
如果你的COLID数量不确定,没法硬编码列名,可以用动态SQL自动生成列:
DECLARE @cols NVARCHAR(MAX), @query NVARCHAR(MAX); -- 自动收集所有不同的COLID,转成带引号的列名 SELECT @cols = STRING_AGG(QUOTENAME(COLID), ', ') FROM (SELECT DISTINCT COLID FROM #TempData) AS c; -- 构建动态Pivot查询 SET @query = N' SELECT SetID, ' + @cols + ', [Order] FROM #TempData PIVOT ( MAX(DataValue) FOR COLID IN (' + @cols + ') ) AS PivotedData ORDER BY [Order];'; -- 执行动态SQL EXEC sp_executesql @query;
这个脚本会自动识别所有存在的COLID,生成对应的列,不管你有3个还是10个COLID都能搞定。
内容的提问来源于stack exchange,提问作者JPicasso
相关产品推荐
相关产品推荐

