Reputation: 623
I am new to Dynamic SQL. I have the following table:
CustName | Date | Hours |
---|---|---|
First | 01/01/2021 | 12 |
Second | 01/01/2021 | 10 |
Second | 05/02/2021 | 1 |
Second | 10/11/2021 | 14 |
I am trying to make a rolling calendar Pivot for the last 12 months of summed hours.
Here is the code I have done:
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;
This works 'kind of' how I want it, but the columns are not ordered from current date backwards.
I'm wanting it to start at the current month backwards. So if this month is August it would be:
CustName | Sep 2020 | .... months | August 2021 |
---|---|---|---|
First | 12 | 14 | |
Second | 3 | 12 |
Is there a good way to start by current month in Dynamic SQL into a pivot and go back 12 months?
I tried 'order by months_ago desc' etc, but that doesn't work
Upvotes: 0
Views: 958
Reputation: 71638
You simply need to add a WHERE
filter. This needs to be in both parts of the query.
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;
You could even pass through a starting date parameter, like this:
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;
Upvotes: 3