Бих настроил вашата заявка малко по-различно, защото въпреки че е динамична, тъй като имената на колоните се променят, вие все още сте кодирали твърдо броя на колоните.
Първо, бих използвал рекурсивен CTE, за да генерирам списъка с месеци/години, които искате да създадете.
DECLARE @startDate datetimeSET @startDate ='2013-01-01';с дати като( изберете @startdate datelist, 1 sp съюз всички изберете dateadd(month, 1, datelist), sp+1 от дати, където sp+1 <=5 -- променете това число 5 на броя месеци, от които се нуждаете) изберете sp, REPLACE(SUBSTRING(CONVERT(varchar(11), datelist, 13), 4, 8), ' ', '') MONTHANDYEARот дати
Вижте SQL Fiddle с демонстрация . Това автоматично ще създаде вашия списък от 5 месеца с годината. Тогава не кодирате твърдо 5-те колони. Текущата ви заявка не е толкова гъвкава, колкото би могла да бъде. Какво ще стане, ако след това искате 12 месеца, ще трябва да промените кода си.
След като генерирате списъка с дати, бих го вмъкнал във временна таблица, за да можете да го използвате, за да получите колоните.
Кодът за получаване на списъка с колони е:
изберете @cols =STUFF((SELECT ',' + QUOTENAME(monthandyear) from #datesTemp group by monthandyear, sp order by sp FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'') изберете @colNames =STUFF((SELECT ', isnull(' + QUOTENAME(monthandyear)+', 0) като '+QUOTENAME(monthandyear) от група #datesTemp от monthandyear, sp ред по sp FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')
Вижте SQL Fiddle с демонстрация
. Ще видите, че има две версии. Първият @cols
получава списъка с колони, които ще бъдат използвани в опорната част
. Вторият @colNames
ще се използва в крайния SELECT
списък за заместване на null
стойности с нули.
След това събирате всичко заедно и кодът ще бъде:(Забележка:Използвам версия на моя отговор от вашия предишен въпрос )
DECLARE @cols AS NVARCHAR(MAX), @colNames AS NVARCHAR(MAX), @query AS NVARCHAR(MAX), @startDate datetimeSET @startDate ='2013-01-01';с дати като ( изберете @startdate списък с дати, 1 sp съюз всички изберете dateadd(месец, 1, списък с дати), sp+1 от дати, където sp+1 <=5 -- променете това число 5 на броя месеци, от които се нуждаете) изберете sp, REPLACE(SUBSTRING (КОНВЕРТИРАНЕ(varchar(11), datelist, 13), 4, 8), ' ', '') MONTHANDYEARinto #datesTempfrom datesselect @cols =STUFF((SELECT ',' + QUOTENAME(monthandyear) from #datesTemp group by monthandyear, sp ред по sp FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')select @colNames =STUFF((SELECT ', isnull(' + QUOTENAME(monthandyear)+', 0) като '+QUOTENAME(monthandyear) от #datesTemp групиране по monthandyear, sp ред по 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 от viewprojscheduling_group ) x осно (сума(FORECASTTOTAL) за месецигодина в (' + @cols + ') ) p 'execute(@query)
Вижте SQL Fiddle с демонстрация . Тази заявка ще ви даде резултата:
<предварителен код>| РЕСУРСИ | ИМЕ НА КЛИЕНТА | ЯНУАРИ 2013 | ФЕВРУАРИ 2013 | МАРТ2013 | април 2013 | МАЙ 2013 |------------------------------------------------ ----------------------------| 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 |