Ich würde Ihre Abfrage etwas anders einrichten, da sie zwar dynamisch ist, da sich die Spaltennamen ändern, Sie die Anzahl der Spalten jedoch fest codiert haben.
Zuerst würde ich einen rekursiven CTE verwenden, um die Liste der Monate/Jahre zu generieren, die Sie erstellen möchten.
DECLARE @startDate datetime
SET @startDate = '2013-01-01'
;with dates as
(
select @startdate datelist, 1 sp
union all
select dateadd(month, 1, datelist), sp+1
from dates
where sp+1 <= 5 -- change this number 5 to the number of months you need
)
select sp,
REPLACE(SUBSTRING(CONVERT(varchar(11), datelist, 13), 4, 8), ' ', '') MONTHANDYEAR
from dates
Siehe SQL-Geige mit Demo . Dadurch wird Ihre Liste der 5 Monate mit dem Jahr automatisch erstellt. Dann codieren Sie die 5 Spalten nicht fest. Ihre aktuelle Abfrage ist nicht so flexibel, wie sie sein könnte. Was passiert, wenn Sie dann 12 Monate wollen, müssen Sie Ihren Code ändern.
Sobald Sie die Datumsliste generiert haben, würde ich sie in eine temporäre Tabelle einfügen, damit Sie sie zum Abrufen der Spalten verwenden können.
Der Code zum Abrufen der Spaltenliste lautet:
select @cols = STUFF((SELECT ',' + QUOTENAME(monthandyear)
from #datesTemp
group by monthandyear, sp
order by sp
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select @colNames = STUFF((SELECT ', isnull(' + QUOTENAME(monthandyear)+', 0) as '+QUOTENAME(monthandyear)
from #datesTemp
group by monthandyear, sp
order by sp
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
Siehe SQL-Geige mit Demo
. Sie werden sehen, dass es zwei Versionen gibt. Der erste @cols
Ruft die Liste der Spalten ab, die im pivot
verwendet werden . Der zweite @colNames
wird im abschließenden SELECT
verwendet Liste zum Ersetzen von null
Werte mit den Nullen.
Dann fügen Sie alles zusammen und der Code lautet:(Hinweis:Ich verwende eine Version meiner Antwort aus Ihrem vorherige Frage )
DECLARE @cols AS NVARCHAR(MAX),
@colNames AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX),
@startDate datetime
SET @startDate = '2013-01-01'
;with dates as
(
select @startdate datelist, 1 sp
union all
select dateadd(month, 1, datelist), sp+1
from dates
where sp+1 <= 5 -- change this number 5 to the number of months you need
)
select sp,
REPLACE(SUBSTRING(CONVERT(varchar(11), datelist, 13), 4, 8), ' ', '') MONTHANDYEAR
into #datesTemp
from dates
select @cols = STUFF((SELECT ',' + QUOTENAME(monthandyear)
from #datesTemp
group by monthandyear, sp
order by sp
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select @colNames = STUFF((SELECT ', isnull(' + QUOTENAME(monthandyear)+', 0) as '+QUOTENAME(monthandyear)
from #datesTemp
group by monthandyear, sp
order by sp
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT resource, clientname,' + @colNames + '
from
(
select [CLIENTNAME], [RESOURCE], [FORECASTTOTAL],
REPLACE(SUBSTRING(CONVERT(varchar(11), SCHEDULEDDATE, 13), 4, 8), '' '', '''') monthandyear
from viewprojscheduling_group
) x
pivot
(
sum(FORECASTTOTAL)
for monthandyear in (' + @cols + ')
) p '
execute(@query)
Siehe SQL Fiddle mit Demo . Diese Abfrage liefert das Ergebnis:
| RESOURCE | CLIENTNAME | JAN2013 | FEB2013 | MAR2013 | APR2013 | MAY2013 |
---------------------------------------------------------------------------
| res1 | abc | 1000 | 2000 | 0 | 0 | 0 |
| res1 | def | 0 | 0 | 2000 | 0 | 0 |
| res2 | def | 1500 | 0 | 0 | 0 | 0 |
| res3 | ghi | 0 | 0 | 2500 | 0 | 0 |