SQL 按日期统计后列转行

以下是带批注的 PIVOT 语法。

SELECT <非透视的列>,

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

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

    ...

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

FROM

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

    AS <源查询的别名>

PIVOT

(

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

FOR

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

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

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

) AS <透视表的别名>

<可选的 ORDER BY 子句>;

示例1:

CREATE TABLE #Product
    (
      DaysToManufacture INT ,
      StandardCost DECIMAL(12, 4)
    );
GO
INSERT  INTO #Product
VALUES  ( 0, 5.0885 );
INSERT  INTO #Product
VALUES  ( 0, 5.0885 );
INSERT  INTO #Product
VALUES  ( 1, 223.88 );
INSERT  INTO #Product
VALUES  ( 1, 223.88 );
INSERT  INTO #Product
VALUES  ( 2, 359.1082 );
INSERT  INTO #Product
VALUES  ( 4, 949.4105 );

SELECT  DaysToManufacture ,
        AVG(StandardCost) AS AverageCost
FROM    #Product
GROUP BY DaysToManufacture;

查询结果:

DaysToManufacture    AverageCost
0    5.088500
1    223.880000
2    359.108200
4    949.410500


-- Pivot table with one row and five columns
SELECT  'AverageCost' AS Cost_Sorted_By_Production_Days ,
        [0] ,
        [1] ,
        [2] ,
        [3] ,
        [4]
FROM    ( SELECT    DaysToManufacture ,
                    StandardCost
          FROM      #Product
        ) AS SourceTable PIVOT
( AVG(StandardCost) FOR DaysToManufacture IN ( [0], [1], [2], [3], [4] ) ) AS PivotTable;

转置结果

Cost_Sorted_By_Production_Days    0    1    2    3    4
AverageCost    5.088500    223.880000    359.108200    NULL    949.410500

现实示例:

1、先统计结果

SELECT
datepart(month,ibb.CreateTime) AS [月份],datepart(day,ibb.CreateTime) as[日期],COUNT(DISTINCT ibb.BillNo) as [单据量],SUM(ibbd.Quantity) as [件数]
FROM InBoundBill ibb (NOLOCK)
        JOIN InBoundBillDetail ibbd (NOLOCK)
                ON IBB.BillId = IBBD.BillId
WHERE ibb.TypeId = 30
        AND ibb.CreateTime > '2012-01-01' AND ibb.CreateTime < '2012-12-21'
        AND ibb.WarehouseId IN (1)
GROUP BY datepart(month,ibb.CreateTime),datepart(day,ibb.CreateTime)
ORDER BY datepart(month,ibb.CreateTime),datepart(day,ibb.CreateTime)

月份 日期 单据量 件数
1 1 492 670
2 399 550
3 487 698
4 487 672
5 507 662
6 605 804
7 666 943
8 439 591
9 599 832
10 530 690
11 554 741
12 631 881
13 574 771
14 577 796
15 409 576
16 420 562
17 445 590
18 667 901
19 406 545
20 427 624
21 320 465
25 3 3
26 241 412
27 214 318
28 180 251
29 342 483
30 162 240
31 360 480

2、列转行

;WITH tmp AS(
SELECT  DATEPART(month , ibb.CreateTime) AS [month] , DATEPART(day , ibb.CreateTime) AS [day] ,
        LTRIM(ISNULL(COUNT(DISTINCT ibb.BillNo) , 0))+'/'+LTRIM(ISNULL(SUM(ibbd.Quantity) , 0)) AS [Quantity]
FROM    InBoundBill ibb (NOLOCK)
JOIN    InBoundBillDetail ibbd (NOLOCK)
ON      IBB.BillId = IBBD.BillId
WHERE   ibb.TypeId = 30
        AND ibb.CreateTime > '2012-01-01'
        AND ibb.CreateTime < '2012-12-21'
        AND ibb.WarehouseId IN (1)
GROUP BY DATEPART(month , ibb.CreateTime) , DATEPART(day , ibb.CreateTime)

)

SELECT  *
FROM    tmp PIVOT ( MAX([Quantity]) FOR [day] IN ([1] , [2] , [3] , [4] , [5] , [6] , [7] , [8] , [9] , [10] , [11] , [12] , [13] , [14] , [15] , [16] , [17] , 

                                                  [18] , [19] , [20] , [21] , [22] , [23] , [24] , [25] , [26] , [27] , [28] , [29] , [30] , [31]) ) piv

ORDER BY [month]

月     日 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
1 492/670 399/550 487/698 487/672 507/662 605/804 666/943 439/591 599/832 530/690 554/741 631/881 574/771 577/796 409/576 420/562 445/590 667/901 406/545 427/624 320/465 0 0 0 3/3 241/412 214/318 180/251 342/483 162/240 360/480
原文地址:https://www.cnblogs.com/pato/p/2828139.html