SELECT piv.[Data], piv.x, piv.y
FROM (
SELECT [Type], ColA = CAST(ColA as varchar(10)), ColB = CAST(ColB as varchar(10)), ColC = CAST(ColC as varchar(10)), ColD = CAST(ColD as varchar(10))
FROM @data
) d
UNPIVOT (
[value] FOR [Data] IN (ColA, ColB, ColC, ColD)
) as unpiv
PIVOT (
MAX([value])
FOR [Type] IN ([x], [y])
) as piv
;
它首先对您的数据进行反透视以获得常规表
然后它将这个表转回新的所需格式
我必须将所有内容都转换为 varchar。根据您的数据模型,您可能必须将它们转换为另一种类型。PIVOT 需要聚合函数。由于这是一对一的匹配,它适用于 MAX 或 MIN。
SELECT piv.[Data], piv.x, piv.y
FROM (
SELECT v.[Type], [value], [Data]
FROM @data d
CROSS APPLY (values
(d.[type], CAST(d.ColA as varchar(10)), 'ColA')
, (d.[type], CAST(d.ColB as varchar(10)) , 'ColB')
, (d.[type], CAST(d.ColC as varchar(10)), 'ColC')
, (d.[type], CAST(d.ColD as varchar(10)), 'ColD')
) as v([type], [value], [Data])
) unpiv
PIVOT (
MAX([value])
FOR [Type] IN ([x], [y])
) as piv
;
如果没有PIVOT / UNPIVOT,您可以将此查询与任何(旧)版本的 SQL Server 一起使用:
SELECT [Data]
, [x] = MAX(CASE WHEN [type] = 'x' THEN [value] END)
, [y] = MAX(CASE WHEN [type] = 'y' THEN [value] END)
FROM (
SELECT [type], [value] = CAST(ColA as varchar(10)), [Data] = 'ColA' FROM @data
UNION ALL
SELECT [type], [value] = CAST(ColB as varchar(10)), [Data] = 'ColB' FROM @data
UNION ALL
SELECT [type], [value] = CAST(ColC as varchar(10)), [Data] = 'ColC' FROM @data
UNION ALL
SELECT [type], [value] = CAST(ColD as varchar(10)), [Data] = 'ColD' FROM @data
) as v
GROUP BY [Data]
输出:
Data x y
ColA 123456 654321
ColB $500 $200
ColC 6 36
ColD 30 90
此查询同时使用UNPIVOT和 PIVOT:
我必须将所有内容都转换为 varchar。根据您的数据模型,您可能必须将它们转换为另一种类型。PIVOT 需要聚合函数。由于这是一对一的匹配,它适用于 MAX 或 MIN。
使用SQL Server >= 2008,您还可以将UNPIVOT替换为Table Value Constructor和CROSS APPLY以及PIVOT:
如果没有PIVOT / UNPIVOT,您可以将此查询与任何(旧)版本的 SQL Server 一起使用:
输出:
数据: