我已经成功地为自己构建了一个漂亮的小 T-SQL 语句,将计划信息转换为每月的列。
SELECT *
FROM
(
SELECT
t1.customer_code,
t1.part_number,
LEFT(DATENAME(month, [formatted_date]),3) as [Month],
t1.quantity as [quantity] FROM FORECAST_VIEW as t1
where
quantity <> 0
and formatted_date >= DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0)
) as p
pivot
(
sum(quantity)
for [Month] in (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec)
) as p
order by customer_code, part_number
这会产生包含列的输出
customer_code, part_number, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
并对每个月所需的 part_number 数量求和。
这工作正常并且在报告中产生了奇迹,但是如果我能让月份列从当前月份开始并按顺序排列 12 个月,那将是锦上添花。
问题是我不知道该怎么做。
如果我今天运行它,输出将是
customer_code, part_number, Nov, Dec, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct
有人有什么建议吗?
谢谢
编辑 我只是想到,如果我找不到解决方案但它很难看,我不会排除。 我可以将整个 T-SQL 语句放在一个 IF block 中
IF LEFT(DATENAME(month, GETDATE()),3) = 'Nov'
BEGIN
SELECT *
FROM
(
...
) as p
pivot
( sum(quantity)
for [Month] in (Nov, Dec, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct)
) as p
order by customer_code, part_number
END
重复 12 次并调整基准月份。
最佳答案
您必须使用动态 SQL 才能实现此目的。
首先,您必须以正确的顺序获取月份名称:
Declare @cols nvarchar(max);
with list as (
Select n, m = Left(DATENAME(month, DATEADD(month, n, getdate())), 3)
From (values (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11)) as x(n)
)
Select @cols = STUFF((
Select ', ' + QUOTENAME(m)
From list
Order By n
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');
@cols 值将为:[Nov]、[Dec]、[Jan]、[Feb]、[Mar]、[Apr]、[May]、[Jun]、[Jul]、[Aug] ], [9 月], [10 月]
然后您可以将您的查询与@cols 混合并执行它:
Declare @sql nvarchar(max);
Set @sql = '
SELECT *
FROM
(
SELECT
t1.customer_code,
t1.part_number,
LEFT(DATENAME(month, [formatted_date]),3) as [Month],
t1.quantity as [quantity] FROM FORECAST_VIEW as t1
where
quantity <> 0
and formatted_date >= DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0)
) as p
pivot
( sum(quantity)
for [Month] in ('+@cols+')
) as p
order by customer_code, part_number;
EXEC sp_executesql @sql;
如果您真的不需要动态列名并且可以在您的代码中使用诸如 [0], [1], ... , [11]
for 12 的列名来处理它一个月前,11 个月前,...直到上个月,那么您可以使用此查询:
SELECT *
FROM
(
SELECT
t1.customer_code,
t1.part_number,
(12 - DATEPART(month, x) + DATEPART(month, getdate())) % 12 as [Month],
t1.quantity as [quantity] FROM FORECAST_VIEW as t1
where
quantity <> 0
and formatted_date >= DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0)
) as p
pivot
(
sum(quantity)
for [Month] in ([0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11])
) as p
order by customer_code, part_number
(12 - DATEPART(month, x) + DATEPART(month, getdate())) % 12
将返回如下值:
Date | Month
2015-11-23 16:11:57.860 | 0
2015-10-23 16:11:57.860 | 1
2015-09-23 16:11:57.860 | 2
2015-08-23 16:11:57.860 | 3
2015-07-23 16:11:57.860 | 4
2015-06-23 16:11:57.860 | 5
2015-05-23 16:11:57.860 | 6
2015-04-23 16:11:57.860 | 7
2015-03-23 16:11:57.860 | 8
2015-02-23 16:11:57.860 | 9
2015-01-23 16:11:57.860 | 10
2014-12-23 16:11:57.860 | 11
关于sql-server - sql server 中的滚动日历枢轴?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33872030/