SQL查询之 Pivot 详解

   Pivot用来生成交差透视报表数据集,也就是所谓的行转列,就是将原来某个字段的全部取值转成列,然后根据一定的分组条件,对某个组并且取值跟该列吻合的数据做汇总统计(平均,求合,计数等),网上都说用pivot比case更简洁了,但是个人觉的理解起来更费劲了,不过从查询分析器中可看到Pivot本质还是case方式实现的

比方如下一个查询:

Declare @bTime datetime,@eTime dateTime
Set @bTime='2011-4-1'
Set @eTime='2012-5-1'

--这里的字段是分组字段跟行转列后的列
--这里的字段取值是,分组字段值,行转列后,组内该列的汇总统计
Select OrgId,OrgName,EmployeId, EmployeName,[1] as Month1,[2] as Month2,[3] as Month3,[4] as Month4,[5] as Month5,[6] as Month6,[7] as Month7,[8] as Month8,[9] as Month9,[10] as Month10,[11] as Month11,[12] as Month12
From(
  --这里面为要进行,行转列的数据源头,可以是任何能生成数据集的查询
  Select  O.OrgId,O.OrgName, E.EmployeId, E.Name As EmployeName, DatePart(month, C.CreateTime) as TimePoint,C.MoneyAmount as Amount
  From  Employe E Inner join Organ   O On O.OrgId=E.OrgId
        Inner join Compact C On C.EmployeId=E.EmployeId
  Where C.Status=2 And C.AuthType=1 And C.MoneyAmount>10 And C.CreateTime>=@bTime And C.CreateTime<@eTime

) as ds

Pivot(

   --统计函数
    Count(amount)

  --行转列的分配依据
    FOR TimePoint  In ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])
   ) as Pvt
Order By EmployeId

上面查询针对销售人员在20xx年合同的签定情况,按员工分组,并以月(CreateTime)为行转列,来展示20xx年员工每月的签单(合同compact)状况

具体执行过程:

上面统计代码首先按指定条件获取20xx年的签单记录,接着按员工分组,组内的统计汇总是按 count(COUNT(CASE WHEN [Month1]=(1) THEN Compact].[MoneyAmount] as [C].[MoneyAmount] ELSE NULL END),.... 的方式形成多个列。

其本质实现还是分组加case语句,参考下图:

完整语法:

SELECT <非透视的列>,

    [第一个透视的列] AS <列名称>,

    [第二个透视的列] AS <列名称>,

    ...

    [最后一个透视的列] AS <列名称>,

FROM

    (<生成数据的 SELECT 查询>)

    AS <源查询的别名>

PIVOT

(

    <聚合函数>(<要聚合的列>)

FOR

[<包含要成为列标题的值的列>]

    IN ( [第一个透视的列], [第二个透视的列],

    ... [最后一个透视的列])

) AS <透视表的别名>

<可选的 ORDER BY 子句>;

原文地址:https://www.cnblogs.com/wdfrog/p/2074032.html