Ian*_*Ian 1 t-sql database sql-server pivot
我已经成功地为自己构建了一个漂亮的小 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
Run Code Online (Sandbox Code Playgroud)
这会产生一个带有列的输出
customer_code, part_number, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
Run Code Online (Sandbox Code Playgroud)
并汇总每个月所需的 part_number 数量。
这工作正常并且在报告中产生奇迹,但是如果我可以让月份列从当前月份开始并按顺序排列 12 个月,那么这将是锦上添花。
问题是我不知道该怎么做。
如果我今天运行它,输出将是
customer_code, part_number, Nov, Dec, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct
Run Code Online (Sandbox Code Playgroud)
有没有人有任何提示?
谢谢
编辑我刚刚想到的一些东西,如果我找不到解决方案,但它很丑陋,我不排除。我可以将整个 T-SQL 语句放在 IF 块中
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
Run Code Online (Sandbox Code Playgroud)
并这样做 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,'');
Run Code Online (Sandbox Code Playgroud)
@cols 值将是: [Nov], [Dec], [Jan], [Feb], [Mar], [Apr], [May], [Jun], [Jul], [Aug], [Sep], [Oct]
然后您可以将您的查询与@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;
Run Code Online (Sandbox Code Playgroud)
如果您真的不需要动态列名并且可以在您的代码中使用列名处理它,例如[0], [1], ... , [11]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
Run Code Online (Sandbox Code Playgroud)
(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
Run Code Online (Sandbox Code Playgroud)