C# 如何在一个存储过程中创建一个动态数据透视表,该存储过程在报表中比当前日期晚12个月?
我无法在SQL语句中从当前日期向后取12个月,以用于我的Stimulsoft报告。sql表结构如下所示(图1),请注意,区域性设置为pt BR(dd/mm/yyyy) 这是SQL表 我想说的是,过去12个月的当前日期是2013年2月1日,因此我们采取:C# 如何在一个存储过程中创建一个动态数据透视表,该存储过程在报表中比当前日期晚12个月?,c#,sql,report,pivot,C#,Sql,Report,Pivot,我无法在SQL语句中从当前日期向后取12个月,以用于我的Stimulsoft报告。sql表结构如下所示(图1),请注意,区域性设置为pt BR(dd/mm/yyyy) 这是SQL表 我想说的是,过去12个月的当前日期是2013年2月1日,因此我们采取: | DACP_Id | FEB 2012 | MAR 2012 | ABR 2012 ... | FEB 2013 。。。以及2013年2月的所有月份。透视表中月份内的行是当前月份的DACP_值 我是SQL新手,希望您能帮助我:)谢谢。从您有
| DACP_Id | FEB 2012 | MAR 2012 | ABR 2012 ... | FEB 2013
。。。以及2013年2月的所有月份。透视表中月份内的行是当前月份的DACP_值
我是SQL新手,希望您能帮助我:)谢谢。从您有限的样本数据很难判断
DACP\u Id
是否会重复多行和多个日期。但是,如果您希望透视一个未知数量的日期或可以随时更改的日期,则需要使用动态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)
看
正如您从演示中看到的,您得到了当月的多行,这是因为
DACP\u 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)
(不知羞耻地从@bluefeet那里偷来,他打败了我,找到了答案)。我在这里留下了这个答案,因为它有点不同,因为它将提供13列(去年和本月),无论表中是否存在该月的数据。我不能对此进行投票,但这也是正确的,除了我要求返回12个月,但无论如何,谢谢@crawletas要获得日期范围,只需包含一个where子句来返回过去的12个月。谢谢,这正是我所需要的