Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

SQL:Menggunakan ISNULL dengan pivot dinamis

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 |



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mengembalikan Daftar Email yang Dikirim dari SQL Server Database Mail (T-SQL)

  2. dapatkan ID catatan SQL baru

  3. Cara Memperbaiki "Server tidak dikonfigurasi untuk AKSES DATA" di SQL Server

  4. dapatkan bagian tanggal hanya dari nilai datetime menggunakan kerangka entitas

  5. Bagaimana cara mengikat parameter ISO8601 TSQL DATETIME dengan PDO?