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

SQL Server-pivottabel med flere kolonneaggregater

Jeg ville gøre dette lidt anderledes ved at anvende både UNPIVOT og PIVOT funktioner for at få det endelige resultat. Unpivot tager værdierne fra både totalcount og totalamount kolonner og placerer dem i én kolonne med flere rækker. Du kan derefter pivotere på disse resultater.:

select chardate,
  Australia_totalcount as [Australia # of Transactions], 
  Australia_totalamount as [Australia Total $ Amount],
  Austria_totalcount as [Austria # of Transactions], 
  Austria_totalamount as [Austria Total $ Amount]
from
(
  select 
    numericmonth, 
    chardate,
    country +'_'+col col, 
    value
  from
  (
    select numericmonth, 
      country, 
      chardate,
      cast(totalcount as numeric(10, 2)) totalcount,
      cast(totalamount as numeric(10, 2)) totalamount
    from mytransactions
  ) src
  unpivot
  (
    value
    for col in (totalcount, totalamount)
  ) unpiv
) s
pivot
(
  sum(value)
  for col in (Australia_totalcount, Australia_totalamount,
              Austria_totalcount, Austria_totalamount)
) piv
order by numericmonth
 

Se SQL Fiddle with Demo.

Hvis du har et ukendt antal country navne, så kan du bruge dynamisk SQL:

DECLARE @cols AS NVARCHAR(MAX),
    @colsName AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(country +'_'+c.col) 
                      from mytransactions
                      cross apply 
                      (
                        select 'TotalCount' col
                        union all
                        select 'TotalAmount'
                      ) c
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colsName 
    = STUFF((SELECT distinct ', ' + QUOTENAME(country +'_'+c.col) 
               +' as ['
               + country + case when c.col = 'TotalCount' then ' # of Transactions]' else 'Total $ Amount]' end
             from mytransactions
             cross apply 
             (
                select 'TotalCount' col
                union all
                select 'TotalAmount'
             ) c
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query 
  = 'SELECT chardate, ' + @colsName + ' 
     from 
     (
      select 
        numericmonth, 
        chardate,
        country +''_''+col col, 
        value
      from
      (
        select numericmonth, 
          country, 
          chardate,
          cast(totalcount as numeric(10, 2)) totalcount,
          cast(totalamount as numeric(10, 2)) totalamount
        from mytransactions
      ) src
      unpivot
      (
        value
        for col in (totalcount, totalamount)
      ) unpiv
     ) s
     pivot 
     (
       sum(value)
       for col in (' + @cols + ')
     ) p 
     order by numericmonth'

execute(@query)
 

Se SQL Fiddle with Demo

Begge giver resultatet:

| CHARDATE | AUSTRALIA # OF TRANSACTIONS | AUSTRALIA TOTAL $ AMOUNT | AUSTRIA # OF TRANSACTIONS | AUSTRIA TOTAL $ AMOUNT | -------------------------------------------------------------------------------------------------------------------------------------- | Jul-12 | 36 | 699.96 | 11 | 257.82 | | Aug-12 | 44 | 1368.71 | 5 | 126.55 | | Sep-12 | 52 | 1161.33 | 7 | 92.11 | | Oct-12 | 50 | 1099.84 | 12 | 103.56 | | Nov-12 | 38 | 1078.94 | 21 | 377.68 | | Dec-12 | 63 | 1668.23 | 3 | 14.35 |

  1. Standard rækkefølge for udvalgt forespørgsel i oracle

  2. Lære 2 og Mange-til-mange linktabel med et ekstra felt

  3. psql:FATAL:Peer-godkendelse mislykkedes for brugerudvikler

  4. Hvordan overfører man værdier til IN-operatøren dynamisk?