动态月度数据透视表

时间:2018-05-07 14:13:43

标签: sql-server sql-server-2012

我有一张发票表,我想创建一个滚动的月度动态数据透视表。我希望当前月份为月份#1;"去年的这个月是月份" 13"

示例数据:

INVOICEDATE | ITEMCODE | UNITS
2018-05-07  | 123456   | 20
2018-05-04  | 123456   | 5
2018-04-07  | 123456   | 10
....
2017-05-25  | 123456   | 50

期望的输出:

ITEMCODE  | 01 | 02 | .... | 13
123456    | 25 | 10 | .... | 50

我从以下开始,但是我对这个月编号/订购件感到困惑,尤其是去年同月进入同一个月。

DECLARE @cols AS NVARCHAR(MAX),
@query  AS NVARCHAR(MAX), 
@NulltoZero nvarchar(max) 

select @cols =   STUFF((SELECT distinct ',' +  
quotename(substring(CONVERT(varchar,INVOICEDATE,112),5,2)) [Month]
FROM MAS_RDP..AR_InvoiceHistoryHeader
where invoicedate >= DATEADD(MONTH, -12, DATEADD(month, DATEDIFF(month, 0, getdate()), 0)) 
order by [Month] DESC
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)') 
,1,1,'') 


select  @NulltoZero =  STUFF((SELECT distinct ',ISNULL(' +  
quotename(substring(CONVERT(varchar,INVOICEDATE,112),5,2)) + ',0) AS ' + quotename(substring(CONVERT(varchar,INVOICEDATE,112),5,2))  
FROM MAS_RDP..AR_InvoiceHistoryHeader
where invoicedate >= DATEADD(MONTH, -12, DATEADD(month, DATEDIFF(month, 0, getdate()), 0)) 
order by ',ISNULL(' +  
quotename(substring(CONVERT(varchar,INVOICEDATE,112),5,2)) + ',0) AS ' + quotename(substring(CONVERT(varchar,INVOICEDATE,112),5,2))  DESC
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)') 
,1,1,'') 


set @query = 'SELECT itemcode, ' + @NulltoZero + ' from 
(
Select ARD.itemcode
,(12 + DATEPART(MONTH, GETDATE()) - DATEPART(MONTH, invoicedate)) % 12 + 1 [MONTH]
,cast(ISNULL(quantityshipped*[UnitOfMeasureConvFactor],0) as int) as units
FROM [MAS_RDP].[dbo].[AR_InvoiceHistoryDetail] ARD 
inner join MAS_RDP..AR_InvoiceHistoryHeader ARH on ARD.InvoiceNo = ARH.InvoiceNo and ARD.HeaderSeqNo = ARH.HeaderSeqNo
inner join MAS_RDP..CI_Item CI on ARD.Itemcode = CI.itemcode and CI.Inactiveitem = ''N'' and CI.itemcode not like ''2%'' and len(ci.itemcode) = 6
inner join MAS_RDP..IM_Itemwarehouse IMW on ARD.itemcode = IMW.itemcode and IMW.warehousecode = ''000'' and imw.udf_is_stocked = ''Y''
where invoicedate >= DATEADD(MONTH, -12, DATEADD(month, DATEDIFF(month, 0, getdate()), 0))
) x
pivot (sum( units  ) for month in (' + @cols + ') ) p 
order by itemcode'
execute(@query)

1 个答案:

答案 0 :(得分:0)

试试这个解决方案。如果我错了,请纠正我,但如果您知道自己需要1到13个月,则不需要动态支点。

在第一个CTE中,我们按月对数据进行分组,然后使用DATEDIFF MONTH计算每个月与当前月份的差异,最后将这些值仅针对月份差异1到13。

IF OBJECT_ID('tempdb..#Data') IS NOT NULL
    DROP TABLE #Data

CREATE TABLE #Data (
    InvoiceDate DATE,
    ItemCode INT,
    Units INT)

INSERT INTO #Data (
    InvoiceDate,
    ItemCode,
    Units)
VALUES
    ('2018-05-07', 123456, 20),
    ('2018-05-04', 123456, 5),
    ('2018-04-07', 123456, 10),
    ('2017-05-25', 123456, 50),
    ('2017-09-07', 123456, 40),
    ('2018-01-07', 123456, 35)

;WITH GroupedMonths AS
(
    SELECT
        ItemCode = D.ItemCode,
        Year = DATEPART(YEAR, D.InvoiceDate),
        Month = DATEPART(MONTH, D.InvoiceDate),
        Units = SUM(D.Units),
        InitialDate = DATEFROMPARTS(
            DATEPART(YEAR, D.InvoiceDate),
            DATEPART(MONTH, D.InvoiceDate),
            1),
        CurrentInitialDate = DATEFROMPARTS(
            DATEPART(YEAR, GETDATE()),
            DATEPART(MONTH, GETDATE()),
            1)
    FROM
        #Data AS D
    GROUP BY
        D.ItemCode,
        DATEPART(YEAR, D.InvoiceDate),
        DATEPART(MONTH, D.InvoiceDate)
),
MonthRankings AS
(
    SELECT
        G.ItemCode,
        G.Units,
        MonthRanking = DATEDIFF(MONTH, G.InitialDate, G.CurrentInitialDate) + 1
    FROM
        GroupedMonths AS G
)
SELECT
    T.ItemCode,
    '01' = ISNULL(T.[1], 0),
    '02' = ISNULL(T.[2], 0),
    '03' = ISNULL(T.[3], 0),
    '04' = ISNULL(T.[4], 0),
    '05' = ISNULL(T.[5], 0),
    '06' = ISNULL(T.[6], 0),
    '07' = ISNULL(T.[7], 0),
    '08' = ISNULL(T.[8], 0),
    '09' = ISNULL(T.[9], 0),
    '10' = ISNULL(T.[10], 0),
    '11' = ISNULL(T.[11], 0),
    '12' = ISNULL(T.[12], 0),
    '13' = ISNULL(T.[13], 0)
FROM
    MonthRankings AS R
    PIVOT (
        MAX(R.Units) FOR R.MonthRanking IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13])
    ) AS T
相关问题