SQL запрос PIVOT - PullRequest
       12

SQL запрос PIVOT

1 голос
/ 06 марта 2019

Я бы хотел упорядочить сумму OrderValue по периоду.Мой SQL-запрос теперь отображается в табличном формате, и я хочу, чтобы он был в одной строке.Если значение OrderValue находится в текущем состоянии, оно должно быть в столбце 0, а если оно должно быть выполнено в следующем месяце, то оно должно быть в столбце 1 и так далее.Пожалуйста, посмотрите мой запрос SQL

ALTER PROCEDURE [dbo].[sp_GetInvoicedPayments]
@CustomerID int   
AS
BEGIN   
DECLARE @endOfCurrentMonth DATE = EOMONTH(GETDATE())

SELECT [data].CustomerID, [data].[Period], SUM([data].OrderValue) AS 
OrderValue 
FROM (
SELECT pms.CustomerID, pms.OrderValue,
        CASE
            WHEN ((SELECT CAST(pms.ExpectedDate AS DATE)) <= paymentInfo.CurrentDueMonth) THEN 0
            WHEN ((SELECT CAST(pms.ExpectedDate AS DATE)) <= DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0, DATEADD(MONTH, 1, paymentInfo.CurrentDueMonth)) + 1,- 1)) ) THEN 1
            WHEN ((SELECT CAST(pms.ExpectedDate AS DATE)) <= DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0, DATEADD(MONTH, 2, paymentInfo.CurrentDueMonth)) + 1,- 1))) THEN  2
            WHEN ((SELECT CAST(pms.ExpectedDate AS DATE)) <= DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0, DATEADD(MONTH, 3, paymentInfo.CurrentDueMonth)) + 1,- 1))) THEN  3
            WHEN ((SELECT CAST(pms.ExpectedDate AS DATE)) <= DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0, DATEADD(MONTH, 4, paymentInfo.CurrentDueMonth)) + 1,- 1))) THEN  4
        END AS [Period]
FROM PaymentMilestoneSummary pms
INNER JOIN (
    SELECT cus.ID AS CustomerID,
    CASE 
        WHEN cus.PaymentStatusID = 1 THEN @endOfCurrentMonth
        WHEN cus.PaymentStatusID = 2 THEN (SELECT CAST(DATEADD(month, - 1, @endOfCurrentMonth) AS DATE))
        WHEN cus.PaymentStatusID = 3 THEN (SELECT CAST(DATEADD(month, - 2, @endOfCurrentMonth) AS DATE))
        WHEN cus.PaymentStatusID = 4 THEN (SELECT CAST(DATEADD(month, - 3, @endOfCurrentMonth) AS DATE))
        WHEN cus.PaymentStatusID = 5 THEN (SELECT CAST(DATEADD(month, - 4, @endOfCurrentMonth) AS DATE))
    END AS CurrentDueMonth
    FROM Company cus 
) paymentInfo ON pms.CustomerID = paymentInfo.CustomerID AND paymentInfo.CustomerID= @CustomerID
)[data]
 GROUP BY [data].CustomerID, [data].[Period]
END

Вот что я получаю:

enter image description here

Это пример того, как я хотел быэто должно быть:

An example of how I want it to be

1 Ответ

3 голосов
/ 06 марта 2019

Вы можете сделать это следующим образом, используя PIVOT и CTE

;with cte as
(
 --wrap you existing query
)

SELECT   
[0], [1], [2], [3], [4]  
FROM  
(select Period, OrderValue from cte) AS SourceTable  
PIVOT  
(  
    max(OrderValue)  
    FOR Period IN ([0], [1], [2], [3], [4])  
) AS PivotTable;  

Ваша процедура должна выглядеть следующим образом.

ALTER PROCEDURE [dbo].[sp_GetInvoicedPayments]
@CustomerID int   
AS
BEGIN   
DECLARE @endOfCurrentMonth DATE = EOMONTH(GETDATE())
;with CTE AS
(
    SELECT [data].CustomerID, [data].[Period], SUM([data].OrderValue) AS 
    OrderValue 
    FROM (
    SELECT pms.CustomerID, pms.OrderValue,
            CASE
                WHEN ((SELECT CAST(pms.ExpectedDate AS DATE)) <= paymentInfo.CurrentDueMonth) THEN 0
                WHEN ((SELECT CAST(pms.ExpectedDate AS DATE)) <= DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0, DATEADD(MONTH, 1, paymentInfo.CurrentDueMonth)) + 1,- 1)) ) THEN 1
                WHEN ((SELECT CAST(pms.ExpectedDate AS DATE)) <= DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0, DATEADD(MONTH, 2, paymentInfo.CurrentDueMonth)) + 1,- 1))) THEN  2
                WHEN ((SELECT CAST(pms.ExpectedDate AS DATE)) <= DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0, DATEADD(MONTH, 3, paymentInfo.CurrentDueMonth)) + 1,- 1))) THEN  3
                WHEN ((SELECT CAST(pms.ExpectedDate AS DATE)) <= DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0, DATEADD(MONTH, 4, paymentInfo.CurrentDueMonth)) + 1,- 1))) THEN  4
            END AS [Period]
    FROM PaymentMilestoneSummary pms
    INNER JOIN (
        SELECT cus.ID AS CustomerID,
        CASE 
            WHEN cus.PaymentStatusID = 1 THEN @endOfCurrentMonth
            WHEN cus.PaymentStatusID = 2 THEN (SELECT CAST(DATEADD(month, - 1, @endOfCurrentMonth) AS DATE))
            WHEN cus.PaymentStatusID = 3 THEN (SELECT CAST(DATEADD(month, - 2, @endOfCurrentMonth) AS DATE))
            WHEN cus.PaymentStatusID = 4 THEN (SELECT CAST(DATEADD(month, - 3, @endOfCurrentMonth) AS DATE))
            WHEN cus.PaymentStatusID = 5 THEN (SELECT CAST(DATEADD(month, - 4, @endOfCurrentMonth) AS DATE))
        END AS CurrentDueMonth
        FROM Company cus 
    ) paymentInfo ON pms.CustomerID = paymentInfo.CustomerID AND paymentInfo.CustomerID= @CustomerID
    )[data]
     GROUP BY [data].CustomerID, [data].[Period]
)

SELECT [0], [1], [2], [3], [4]  
FROM  
(select Period, OrderValue from cte) AS SourceTable  
PIVOT  
(  
    max(OrderValue)  
    FOR Period IN ([0], [1], [2], [3], [4])  
) AS PivotTable; 

END

Редактировать:

как бы я суммировал те значения, которые я получил из этой строки?

Чтобы подвести итог, вы можете изменить сводный запрос следующим образом.

SELECT   
[0], [1], [2], [3], [4] , s as [Sum]
FROM  
(select Period, OrderValue, sum(OrderValue) over() s from cte) AS SourceTable  
PIVOT  
(  
    max(OrderValue)  
    FOR Period IN ([0], [1], [2], [3], [4])  
) AS PivotTable;  
...