如何在存储过程中创建动态数据透视表,该存储过程需要报表中当前日期的 12 个月
本文关键字:存储过程 报表 当前日期 个月 存储 过程中 创建 透视 数据 动态 | 更新日期: 2023-09-27 17:56:54
我无法在SQL语句中从当前日期返回12个月以用于我的Stimulsoft报告。sql 表结构是这样的(图 1),请注意,im 是巴西语,因此区域性设置为 pt-BR (日/月/年)
这是 SQL 表
http://img534.imageshack.us/img534/1093/clipboard02xva.jpg
我想这样做,过去 12 个月的当前日期是 01/02/2013,所以我们采取:
| DACP_Id | FEB 2012 | MAR 2012 | ABR 2012 ... | FEB 2013
。以及追溯到 2013 年 2 月的所有月份。数据透视表中月份内的行是当月DACP_Value。
我是SQL新手,所以我希望你能帮助:)谢谢。
很难从有限的样本数据中判断DACP_Id
是否会重复多行和多日期。但是,如果要PIVOT
未知数量的日期或可以随时更改的日期,则需要使用动态SQL。
您的代码将类似于以下内容:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(DateName(month, DACP_date) +'_'+cast(Datepart(year, DACP_Date) as varchar(10)))
from yourtable
group by Datepart(month, DACP_date), Datepart(year, DACP_Date), DACP_date
order by DACP_date
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query
= 'select DACP_id, '+@cols+'
from
(
select DACP_id,
DateName(month, DACP_date) +''_''+cast(Datepart(year, DACP_Date) as varchar(10)) date,
DACP_Value
from yourtable
) p
pivot
(
sum(DACP_Value)
for date in('+@cols+')
) piv'
execute(@query)
请参阅带有演示的 SQL 小提琴
从演示中可以看出,您获得月份的多行,这是因为示例数据中的DACP_ID
不同。但这就是你在不提前知道价值观的情况下进行转向的方式。
我倾向于不使用动态透视,而是处理应用程序代码中的标头:
WITH Data AS
( SELECT DACP_ID,
DACP_Value,
[MonthNum] = 12 - DATEDIFF(MONTH, DACP_Date, CURRENT_TIMESTAMP)
FROM T
WHERE DATEDIFF(MONTH, DACP_Date, CURRENT_TIMESTAMP) BETWEEN 0 AND 12
)
SELECT *
FROM Data
PIVOT
( SUM(DACP_Value)
FOR MonthNum IN ([0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12])
) pvt;
如果您确实需要列标题,请使用:
DECLARE @Col NVARCHAR(MAX) =
( SELECT ', ' + QUOTENAME(CONVERT(VARCHAR, DATEADD(MONTH, DATEDIFF(MONTH, 0, CURRENT_TIMESTAMP) - (12 - Number), 0), 112)) + ' = [' + CAST(number AS VARCHAR) + ']'
FROM Master..spt_values
WHERE Type = 'P'
AND number BETWEEN 0 AND 12
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)');
DECLARE @SQL NVARCHAR(MAX) =
N'WITH Data AS
( SELECT DACP_ID,
DACP_Value,
[MonthNum] = 12 - DATEDIFF(MONTH, DACP_Date, CURRENT_TIMESTAMP)
FROM T
WHERE DATEDIFF(MONTH, DACP_Date, CURRENT_TIMESTAMP) BETWEEN 0 AND 12
)
SELECT DACP_ID' + @Col + '
FROM Data
PIVOT
( SUM(DACP_Value)
FOR MonthNum IN ([0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12])
) pvt;';
EXECUTE SP_EXECUTESQL @SQL;
您可以将日期转换为 varchar 时更改值112
更改为各种数字,以更改列标题中日期的格式(如问题中所述,103 将为您提供 dd/mm/yyyy)。
SQL Fiddle(无耻地从@bluefeet那里偷来的,谁打败了我)。我在这里留下了这个答案,因为它略有不同,因为它将提供 13 列(去年和本月),无论表中是否存在该月的数据。