Saya akan mengatur kueri Anda sedikit berbeda karena meskipun dinamis karena nama kolom berubah, Anda masih membuat kode keras jumlah kolom.
Pertama, saya akan menggunakan CTE rekursif untuk membuat daftar bulan/tahun yang ingin Anda buat.
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
Lihat SQL Fiddle dengan Demo . Ini akan membuat daftar 5 bulan Anda dengan tahun secara otomatis. Maka Anda tidak melakukan hard-coding pada 5 kolom. Permintaan Anda saat ini tidak sefleksibel mungkin. Apa yang akan terjadi jika Anda ingin 12 bulan, Anda harus mengubah kode Anda.
Setelah Anda membuat daftar tanggal, saya akan memasukkannya ke dalam tabel sementara sehingga Anda dapat menggunakannya untuk mendapatkan kolom.
Kode untuk mendapatkan daftar kolom adalah:
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,'')
Lihat SQL Fiddle dengan Demo
. Anda akan melihat bahwa ada dua versi. Yang pertama @cols
mendapatkan daftar kolom yang akan digunakan di pivot
. @colNames
kedua akan digunakan dalam SELECT
final terakhir list untuk menggantikan null
nilai dengan nol.
Kemudian Anda menggabungkan semuanya dan kodenya akan menjadi:(Catatan:Saya menggunakan versi jawaban saya dari pertanyaan sebelumnya )
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)
Lihat SQL Fiddle dengan Demo . Kueri ini akan memberi Anda hasil:
| 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 |