Tôi sẽ thiết lập truy vấn của bạn hơi khác một chút bởi vì trong khi truy vấn động trong đó tên cột thay đổi, bạn vẫn mã hóa số lượng cột.
Đầu tiên, tôi sẽ sử dụng CTE đệ quy để tạo danh sách tháng / năm mà bạn muốn tạo.
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
Xem SQL Fiddle with Demo . Thao tác này sẽ tự động tạo danh sách 5 tháng với năm của bạn. Sau đó, bạn không phải mã hóa cứng 5 cột. Truy vấn hiện tại của bạn không linh hoạt như có thể. Điều gì sẽ xảy ra nếu bạn muốn sau 12 tháng, bạn sẽ phải thay đổi mã của mình.
Sau khi bạn tạo danh sách ngày tháng, tôi sẽ chèn nó vào bảng tạm thời để bạn có thể sử dụng nó để lấy các cột.
Mã để lấy danh sách các cột là:
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,'')
Xem SQL Fiddle with Demo
. Bạn sẽ thấy rằng có hai phiên bản. Địa chỉ đầu tiên @cols
lấy danh sách các cột sẽ được sử dụng trong pivot
. @colNames
thứ hai sẽ được sử dụng trong SELECT
cuối cùng danh sách để thay thế null
giá trị bằng các số không.
Sau đó, bạn tập hợp tất cả lại với nhau và mã sẽ là:(Lưu ý:Tôi đang sử dụng phiên bản câu trả lời của mình từ câu hỏi trước )
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)
Xem SQL Fiddle với Demo . Truy vấn này sẽ cho bạn kết quả:
| 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 |