簡體   English   中英

如何在SQL中創建計算的樞軸

[英]how to create calculated pivot in sql

腳本

XYZ公司銷售產品。 公司通過檢查完成整個訂單需要多長時間來衡量其績效。 每個訂單都經歷多個狀態(例如:未結,待定,結清)

他們計算每種狀態的天數,以了解特定狀態下訂單的天數。 這些天以兩種不同的方式計算,即“工作日”和“日歷日”

請參考下表:

在此處輸入圖片說明

如何將此表轉換為下圖所示的數據透視表? 以及如何添加到每個工作日和工作日狀態總計的其他列中。

所需結果:

在此處輸入圖片說明

你可以這樣做:

SELECT *
FROM
(
    SELECT 
        OrderID,
        OrderStatus + CountType AS StatusType,
        DayCount
    FROM CalendarTable     
    UNION ALL
    SELECT 
    OrderID,
    CASE WHEN CountType = 'Working' THEN 'TotalWorking' ELSE 'TotalCalendar' END,
    DayCount
    FROM CalendarTable
) AS t
PIVOT
(
   MAX(DayCount)
   For StatusType IN(OpenWorking,
                     OpenCalendar,
                     CloseWorking,
                     CloseCalendar,
                     PendingWorking,
                     PendingCalendar,
                     TotalWorking,
                     TotalCalendar)
) AS p;

這將為您提供:

在此處輸入圖片說明


如果您不想手動寫下所有狀態,則可以動態執行ti:

聲明@cols AS NVARCHAR(MAX);

DECLARE @query AS NVARCHAR(MAX);

SELECT @cols = STUFF((SELECT distinct ',' +
                        QUOTENAME(StatusType)
                       FROM 
                       (
                            SELECT 
                              OrderID,
                              OrderStatus + CountType AS StatusType,
                              DayCount
                            FROM CalendarTable     
                            UNION ALL
                            SELECT 
                              OrderID,
                              CASE WHEN CountType = 'Working' THEN 'TotalWorking' ELSE 'TotalCalendar' END,
                              DayCount
                            FROM CalendarTable
                        ) AS t
                      FOR XML PATH(''), TYPE
                     ).value('.', 'NVARCHAR(MAX)') 
                        , 1, 1, '');


SELECT @query = 'SELECT *
                FROM
                (
                    SELECT 
                      OrderID,
                      OrderStatus + CountType AS StatusType,
                      DayCount
                    FROM CalendarTable     
                    UNION ALL
                    SELECT 
                      OrderID,
                      CASE WHEN CountType = ''Working'' THEN ''TotalWorking'' ELSE ''TotalCalendar'' END,
                      DayCount
                    FROM CalendarTable
                ) AS t
                PIVOT
                (
                   MAX(DayCount)
                   For StatusType IN(' + @cols + ')' +
                  ') p';

execute(@query);

更新:

對於列名,您可以創建一個新變量@colnames ,並使用所需的名稱填充它。 對於總計,您可以添加WHERE子句以獲取僅活動狀態和未決狀態的總計。 因此,您的查詢將如下所示:

DECLARE @cols AS NVARCHAR(MAX);
DECLARE @colnames AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);

SELECT @cols = STUFF((SELECT distinct ',' +
                        QUOTENAME(StatusType)
                       FROM 
                       (
                            SELECT 
                              OrderID,
                              OrderStatus + CountType AS StatusType,
                              DayCount
                            FROM CalendarTable     
                            UNION ALL
                            SELECT 
                              OrderID,
                              CASE WHEN CountType = 'Working' THEN 'TotalWorking' ELSE 'TotalCalendar' END,
                              DayCount
                            FROM CalendarTable
                            WHERE OrderStatus IN('Active', 'Pending')
                        ) AS t
                      FOR XML PATH(''), TYPE
                     ).value('.', 'NVARCHAR(MAX)') 
                        , 1, 1, '');


SELECT @colnames = STUFF((SELECT distinct ',' +
                        QUOTENAME(StatusType) + ' AS ' + QUOTENAME(StatusTypeName)
                       FROM 
                       (
                           SELECT 
                                OrderID,
                                OrderStatus + CountType AS StatusType,
                                DayCount,
                                OrderStatus + CASE WHEN CountType = 'Working' THEN  'WorkDays' ELSE 'CalDays' END AS StatusTypeName
                            FROM CalendarTable     
                            UNION ALL
                            SELECT 
                              OrderID,
                              CASE WHEN CountType = 'Working' THEN 'TotalWorking' ELSE 'TotalCalendar' END,
                              DayCount,
                              CASE WHEN CountType = 'Working' THEN 'TotalWorking' ELSE 'TotalCalendar' END
                            FROM CalendarTable
                            WHERE OrderStatus IN('Active', 'Pending')
                        ) AS t
                      FOR XML PATH(''), TYPE
                     ).value('.', 'NVARCHAR(MAX)') 
                        , 1, 1, '');

SELECT @query = 'SELECT OrderID , ' + @colnames + '
                FROM
                (
                    SELECT 
                      OrderID,
                      OrderStatus + CountType AS StatusType,
                      DayCount
                    FROM CalendarTable     
                    UNION ALL
                    SELECT 
                      OrderID,
                      CASE WHEN CountType = ''Working'' THEN ''TotalWorking'' ELSE ''TotalCalendar'' END,
                      DayCount
                    FROM CalendarTable
                    WHERE OrderStatus IN(''Active'', ''Pending'')
                ) AS t
                PIVOT
                (
                   SUM(DayCount)
                   For StatusType IN(' + @cols + ')' +
                  ') p';

execute(@query);

這將為您提供:

在此處輸入圖片說明


更新

如果要在手動數據透視查詢中添加where子句,則可以執行以下操作:

SELECT *
FROM
(
    SELECT 
        OrderID,
        OrderStatus + CountType AS StatusType,
        DayCount
    FROM CalendarTable     
    WHERE ...
    UNION ALL
    SELECT 
    OrderID,
    CASE WHEN CountType = 'Working' THEN 'TotalWorking' ELSE 'TotalCalendar' END,
    DayCount
    FROM CalendarTable
    WHERE ...
) AS t
PIVOT
(
   MAX(DayCount)
   For StatusType IN(OpenWorking,
                     OpenCalendar,
                     CloseWorking,
                     CloseCalendar,
                     PendingWorking,
                     PendingCalendar,
                     TotalWorking,
                     TotalCalendar)
) AS p;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM