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

Enkel måde at transponere kolonner og rækker i SQL?

Der er flere måder, hvorpå du kan transformere disse data. I dit oprindelige indlæg angav du at PIVOT virker for komplekst til dette scenarie, men det kan anvendes meget nemt ved at bruge både UNPIVOT og PIVOT funktioner i SQL Server.

Men hvis du ikke har adgang til disse funktioner, kan dette replikeres ved hjælp af UNION ALL til UNPIVOT og derefter en aggregeret funktion med en CASE sætning til PIVOT :

Opret tabel:

CREATE TABLE yourTable([color] varchar(5), [Paul] int, [John] int, [Tim] int, [Eric] int);

INSERT INTO yourTable
    ([color], [Paul], [John], [Tim], [Eric])
VALUES
    ('Red', 1, 5, 1, 3),
    ('Green', 8, 4, 3, 5),
    ('Blue', 2, 2, 9, 1);
 

Union All, Aggregate og CASE-version:

select name,
  sum(case when color = 'Red' then value else 0 end) Red,
  sum(case when color = 'Green' then value else 0 end) Green,
  sum(case when color = 'Blue' then value else 0 end) Blue
from
(
  select color, Paul value, 'Paul' name
  from yourTable
  union all
  select color, John value, 'John' name
  from yourTable
  union all
  select color, Tim value, 'Tim' name
  from yourTable
  union all
  select color, Eric value, 'Eric' name
  from yourTable
) src
group by name
 

Se SQL Fiddle with Demo

UNION ALL udfører UNPIVOT af dataene ved at transformere kolonnerne Paul, John, Tim, Eric i separate rækker. Derefter anvender du den samlede funktion sum() med case sætning for at få de nye kolonner for hver color .

Unpivot og Pivot Static Version:

Både UNPIVOT og PIVOT funktioner i SQL server gør denne transformation meget lettere. Hvis du kender alle de værdier, du vil transformere, kan du hardkode dem til en statisk version for at få resultatet:

select name, [Red], [Green], [Blue]
from
(
  select color, name, value
  from yourtable
  unpivot
  (
    value for name in (Paul, John, Tim, Eric)
  ) unpiv
) src
pivot
(
  sum(value)
  for color in ([Red], [Green], [Blue])
) piv
 

Se SQL Fiddle with Demo

Den indre forespørgsel med UNPIVOT udfører den samme funktion som UNION ALL . Den tager listen over kolonner og omdanner den til rækker, PIVOT udfører derefter den endelige transformation til kolonner.

Dynamisk pivotversion:

Hvis du har et ukendt antal kolonner (Paul, John, Tim, Eric i dit eksempel) og derefter et ukendt antal farver, der skal transformeres, kan du bruge dynamisk sql til at generere listen til UNPIVOT og derefter PIVOT :

DECLARE @colsUnpivot AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @colsPivot as  NVARCHAR(MAX)

select @colsUnpivot = stuff((select ','+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('yourtable') and
               C.name <> 'color'
         for xml path('')), 1, 1, '')

select @colsPivot = STUFF((SELECT  ',' 
                      + quotename(color)
                    from yourtable t
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query 
  = 'select name, '[email protected]+'
      from
      (
        select color, name, value
        from yourtable
        unpivot
        (
          value for name in ('[email protected]+')
        ) unpiv
      ) src
      pivot
      (
        sum(value)
        for color in ('[email protected]+')
      ) piv'

exec(@query)
 

Se SQL Fiddle with Demo

Den dynamiske version forespørger både yourtable og derefter sys.columns tabel for at generere listen over elementer til UNPIVOT og PIVOT . Dette føjes derefter til en forespørgselsstreng, der skal udføres. Fordelen ved den dynamiske version er, hvis du har en skiftende liste over colors og/eller names dette vil generere listen ved kørsel.

Alle tre forespørgsler vil give det samme resultat:

| NAME | RED | GREEN | BLUE | ----------------------------- | Eric | 3 | 5 | 1 | | John | 5 | 4 | 2 | | Paul | 1 | 8 | 2 | | Tim | 1 | 3 | 9 |

  1. ændre størrelsen på datatype i sql

  2. Eksporter SQLite-database til en CSV-fil

  3. Rails 3.1 - Pushing to Heroku - Fejl ved installation af postgres adapter?

  4. Android SQLite Journal-adfærd ændret?