动态 SQL 滚动 12 个月枢轴

Dynamic SQL Rolling 12 Months Pivot

我是 Dynamic 的新手 SQL。我有以下 table:

客户名称 日期 小时
第一个 2021 年 1 月 1 日 12
第二 2021 年 1 月 1 日 10
第二 05/02/2021 1
第二 10/11/2021 14

我正在尝试为过去 12 个月的总时数制作滚动日历枢轴。

这是我完成的代码:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

    select @cols = STUFF(
    (SELECT distinct ',' + QUOTENAME(DATENAME(mm,Date) + ' of ' 
    + DATENAME(year,Date)) AS months_ago
          FROM [TimeEntryList]  
          WHERE Date > DATEADD(year, -1, 
    DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1))
    FOR XML PATH(''), TYPE
    ).value('.', 'NVARCHAR(MAX)') 
,1,1,'')


 set @query = 'SELECT CustName, ' + @cols + ' 
 from ( select 
   [CustName], 
   datename(mm,[Date])+'' of ''+datename(year,[Date])AS 
   months_ago, [Hours] AS NetQty 
   from [TimeEntryList] 
    WHERE [Date] > DATEADD(year, -1, 
  DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1))
 ) as source 
 pivot 
 ( 
 sum(NetQty) For months_ago  in (' + @cols + ')
 ) as PivotTable'

execute sp_executesql @query;

这有效'kind of'我想要的方式,但列不是从当前日期向后排序的。

我希望它从当前月份开始倒退。所以如果这个月是八月,它将是:

客户名称 2020 年 9 月 ..... 个月 2021 年 8 月
第一个 12 14
第二 3 12

有没有一种好的方法可以在动态 SQL 中从当月开始进入一个枢轴并返回 12 个月?

我尝试了 'order by months_ago desc' 等,但没有用

您只需添加一个 WHERE 过滤器。 这需要在查询的两个部分中。

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX);

SET @cols = STUFF(
    (SELECT ',' + QUOTENAME(DATENAME(mm, EOMONTH(Date)) + ' of ' + DATENAME(year, EOMONTH(Date))) AS months_ago
    FROM [TimeEntryList]  
    WHERE [Date] > DATEADD(year, -1, DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1))
    GROUP BY EOMONTH(Date)
    ORDER BY EOMONTH(Date)
    FOR XML PATH(''), TYPE
    ).value('text()[1]', 'NVARCHAR(MAX)') 
,1,1,'');

SET @query = '
SELECT
  CustName,
  ' + @cols + ' 
from (
  select 
    [CustName], 
    datename(mm,[Date])+'' of ''+datename(year,[Date])AS months_ago, [Hours] AS 
    NetQty 
   from [TimeEntryList]
   WHERE [Date] > DATEADD(year, -1, DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1))
 ) as source 
pivot 
  ( 
   sum(NetQty) For months_ago  in (' + @cols + ')
  ) as PivotTable;
';

execute sp_executesql @query;

您甚至可以传递开始日期参数,如下所示:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @dateFrom datetime;

SET @dateFrom = DATEADD(year, -1, DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1));

SET @cols = STUFF(
    (SELECT ',' + QUOTENAME(DATENAME(mm,EOMONTH(Date)) + ' of ' + DATENAME(year,EOMONTH(Date)) AS months_ago
    FROM [TimeEntryList]  
    WHERE [Date] > @dateFrom
    GROUP BY EOMONTH(Date)
    ORDER BY EOMONTH(Date)
    FOR XML PATH(''), TYPE
    ).value('text()[1]', 'NVARCHAR(MAX)') 
,1,1,'');

SET @query = '
SELECT
  CustName,
  ' + @cols + ' 
from (
  select 
    [CustName], 
    datename(mm,[Date])+'' of ''+datename(year,[Date])AS months_ago, [Hours] AS 
    NetQty 
   from [TimeEntryList]
   WHERE [Date] > @dateFrom
 ) as source 
pivot 
  ( 
   sum(NetQty) For months_ago  in (' + @cols + ')
  ) as PivotTable;
';

execute sp_executesql
    @query
    N'@dateFrom datetime',
    @dateFrom = @dateFrom;