我有一张发票表,我想创建一个滚动的月度动态数据透视表。我希望当前月份为月份#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)
答案 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