sql >> Database teknologi >  >> RDS >> Sqlserver

SQL:Brug af ISNULL med dynamisk pivot

Jeg ville indstille din forespørgsel lidt anderledes, fordi selvom den er dynamisk, fordi kolonnenavnene ændres, har du stadig hårdkodet antallet af kolonner.

Først ville jeg bruge en rekursiv CTE til at generere listen over måneder/år, som du vil oprette.

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
 

Se SQL Fiddle with Demo . Dette vil automatisk oprette din liste over de 5 måneder med året. Så hårdkoder du ikke de 5 kolonner. Din nuværende forespørgsel er ikke så fleksibel, som den kunne være. Hvad vil der ske, hvis du så vil have 12 måneder, du bliver nødt til at ændre din kode.

Når du har genereret listen over datoer, ville jeg indsætte den i en midlertidig tabel, så du kan bruge den til at hente kolonnerne.

Koden til at få listen over kolonner er:

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,'')
 

Se SQL Fiddle with Demo . Du vil se, at der er to versioner. Den første @cols henter listen over kolonner, der vil blive brugt i pivot . Den anden @colNames vil blive brugt i den endelige SELECT liste for at erstatte null værdier med nuller.

Så sætter du det hele sammen, og koden bliver:(Bemærk:Jeg bruger en version af mit svar fra din tidligere spørgsmål )

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)
 

Se SQL Fiddle with Demo . Denne forespørgsel vil give dig resultatet:

| 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. Shell-script til at udføre pgsql-kommandoer i filer

  2. Oprettelse af en PostgreSQL-replikeringsopsætning på Debian / Ubuntu

  3. Håndhævelse af unik/primær nøgle - drop index

  4. Hvordan får man summen af ​​tid fra databasen i PHP?