Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

SQL:Sử dụng ISNULL với trục động

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 |



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tìm kiếm CHARINDEX và LIKE cho hiệu suất rất khác nhau, tại sao?

  2. SQL chỉ lấy các giá trị số từ một varchar

  3. Mọi thứ bạn nên biết về SQL Server JOINS

  4. Lỗi truy vấn với tên cột không rõ ràng trong SQL

  5. Làm cách nào để chuyển một biến có chứa danh sách vào một truy vấn SQL động?