在该示例中,隐含的 group-by 列表为 OrderYear 和 OrderMonth,因为 CustomerID 和 Quantity 分别被用作枢轴列和值列。
但是,如果您希望年份值和月份值的组合显示为列,则必须首先自己串联它们,然后再将它们传递给 PIVOT 运算符,因为只能有一个枢轴列:
SELECT *
FROM (SELECT CustomerID, OrderYear*100+OrderMonth AS YM, Quantity
FROM OrdersFact
WHERE CustomerID BETWEEN 1 AND 9
AND OrderYear IN(2003, 2004)
AND OrderMonth IN(1, 2, 3)) AS ORD
PIVOT
(
SUM(Quantity)
FOR YM IN([200301],[200302],[200303],[200401],[200402],[200403])
) AS PVT
以下为结果集:
CustomerID 200301 200302 200303 200401 200402 200403
---------- ------ ------ ------ ------ ------ ------
2 NULL 5 NULL NULL 10 NULL
3 NULL NULL 105 NULL NULL 103
6 NULL NULL NULL NULL NULL 4
4 105 NULL NULL 80 NULL NULL
8 NULL NULL NULL NULL 6 NULL
5 NULL NULL 15 NULL NULL 25
7 8 NULL NULL NULL NULL NULL
9 NULL 15 NULL NULL 3 NULL
UNPIVOT
UNPIVOT 运算符使您可以标准化预先旋转的数据。UNPIVOT 运算符的语法和元素与 PIVOT 运算符类似。
例如,请考虑上一节中的 AuctionItems 表:
itemid itemtype whenmade initialprice
----------- ------------------------ ----------- --------------
1 Wine 1822 3000.0000
2 Wine 1807 500.0000
3 Chair 1753 800000.0000
4 Ring -501 1000000.0000
5 Painting 1873 8000000.0000
6 Painting 1889 8000000.0000
假设您希望每个属性出现在不同的行中(类似于在 ItemAttributes 表中保存属性的方式):
itemid attribute value
----------- --------------- -------
1 itemtype Wine
1 whenmade 1822
1 initialprice 3000.00
2 itemtype Wine
2 whenmade 1807
2 initialprice 500.00
3 itemtype Chair
3 whenmade 1753
3 initialprice 800000.00
4 itemtype Ring
4 whenmade -501
4 initialprice 1000000.00
5 itemtype Painting
5 whenmade 1873
5 initialprice 8000000.00
6 itemtype Painting
6 whenmade 1889
6 initialprice 8000000.00
在 UNPIVOT 查询中,您希望将列 itemtype、whenmade 和 initialprice 旋转到行。每个行都应当具有项 ID、属性和值。您必须提供的新的列名称为 attribute 和 value。它们对应于 PIVOT 运算符中的 pivot_column 和 value_column。attribute 列应当获得您希望旋转的实际列名称(itemtype、whenmade 和 initialprice)作为值。value 列应当将来自三个不同源列中的值放到一个目标列中。为了有助于进行说明,首先介绍一个无效的 UNPIVOT 查询版本,然后介绍一个应用了某些限制的有效版本:
SELECT itemid, attribute, value
FROM AuctionItems
UNPIVOT
(
value FOR attribute IN([itemtype], [whenmade], [initialprice])
) AS UPV
作为 PIVOT 运算符的参数,您为后面跟 FOR 子句的 value_column(在该示例中为 value)提供一个名称。在 FOR 子句后面,为 pivot_column(在该示例中为 attribute)提供一个名称,然后提供一个 IN 子句,其中带有您希望获得以作为 pivot_column 中的值的源列名称的列表。在 PIVOT 运算符中,该列列表被引用为<column_list> 。该查询生成以下错误:
.Net SqlClient Data Provider:Msg 8167, Level 16, State 1, Line 1
Type of column ''whenmade'' conflicts with the type of other columns specified in the UNPIVOT list.
目标 value 列包含源自多个不同源列(那些出现在<column_list> 中的列)的值。因为所有列值的目标是单个列,所以 UNPIVOT 要求<column_list> 中的所有列都具有相同的数据类型、长度和精度。要满足该限制,可以向 UNPIVOT 运算符提供一个