PIVOT 提供的语法比一系列复杂的 SELECT...CASE 语句中所指定的语法更简单和更具可读性。
以下是带批注的 PIVOT 语法:
SELECT <非透视的列>,
[第一个透视的列] AS <列名称>,
[第二个透视的列] AS <列名称>,
...
[最后一个透视的列] AS <列名称>,
FROM
(<生成数据的 SELECT 查询>)
AS <源查询的别名>
PIVOT
(
<聚合函数>(<要聚合的列>)
FOR
[<包含要成为列标题的值的列>]
IN ( [第一个透视的列], [第二个透视的列],
... [最后一个透视的列])
) AS <透视表的别名>
<可选的 ORDER BY 子句>;
下面举个实例,比如要统计亚马逊9月1号一天每个小时下发的订单量,按照传统的写法如下所示:
select Warehouseid 仓库,
CustomerID 客户,
SUBSTRING(CONVERT(varchar(100),OrderTime,120),0,11) WMS创建时间,
SUBSTRING(CONVERT(varchar(100), ordertime, 120),12,2) 小时,
count(OrderNo) 订单量
from DOC_Order_Header
where
OrderTime>='2018-09-01 00:00:00'
and OrderTime<='2018-09-01 23:59:59'
and CustomerID ='YMX'
and Warehouseid in('HKBT','FLC')
group by Warehouseid,CustomerID,SUBSTRING(CONVERT(varchar(100),OrderTime,120),0,11),
SUBSTRING(CONVERT(varchar(100), ordertime, 120),12,2)
order by 仓库,WMS创建时间
查询出来的结果为列模式,看起来不方便,如下所示:
现在使用 PIVOT 函数,把列转成行,看起来直观明了,语法如下所示:
select *,
[00]+[01]+[02]+[03]+[04]+[05]+[06]+[07]+[08]+[09]+[10]+[11]+
[12]+[13]+[14]+[15]+[16]+[17]+[18]+[19]+[20]+[21]+[22]+[23]+[24] as 当天订单总数
from
(
select Warehouseid 仓库,
CustomerID 客户,
SUBSTRING(CONVERT(varchar(100),OrderTime,120),0,11) WMS创建时间,
SUBSTRING(CONVERT(varchar(100), ordertime, 120),12,2) 小时,OrderNo
from DOC_Order_Header
where
OrderTime>='2018-09-01 00:00:00'
and OrderTime<='2018-09-01 23:59:59'
and CustomerID ='YMX'
and Warehouseid in('HKBT','FLC')
)t
PIVOT
(
count(t.OrderNo) FOR t.小时 IN
([00],[01],[02],[03],[04],[05],[06],[07],[08],[09],[10],[11],
[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23],[24])
)as a
order by a.仓库,a.WMS创建时间
查询结果如下图所示: