Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Prosty sposób na transponowanie kolumn i wierszy w SQL?

Istnieje kilka sposobów przekształcania tych danych. W oryginalnym poście stwierdziłeś, że PIVOT wydaje się zbyt skomplikowany dla tego scenariusza, ale można go bardzo łatwo zastosować za pomocą zarówno UNPIVOT i PIVOT funkcje w SQL Server.

Jeśli jednak nie masz dostępu do tych funkcji, można je zreplikować za pomocą UNION ALL do UNPIVOT a następnie funkcję agregującą z CASE oświadczenie do PIVOT :

Utwórz 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);

Wersja Union All, Aggregate i CASE:

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

Zobacz SQL Fiddle z demonstracją

UNION ALL wykonuje UNPIVOT danych poprzez przekształcenie kolumn Paul, John, Tim, Eric w osobne rzędy. Następnie stosujesz funkcję agregującą sum() z case oświadczenie, aby uzyskać nowe kolumny dla każdego color .

Wersje statyczne Unpivot i Pivot:

Zarówno UNPIVOT i PIVOT funkcje w serwerze SQL znacznie ułatwiają tę transformację. Jeśli znasz wszystkie wartości, które chcesz przekształcić, możesz je na stałe zakodować w wersji statycznej, aby uzyskać wynik:

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

Zobacz SQL Fiddle z demonstracją

Zapytanie wewnętrzne z UNPIVOT wykonuje tę samą funkcję co UNION ALL . Pobiera listę kolumn i zamienia ją w wiersze, PIVOT następnie wykonuje ostateczną transformację w kolumny.

Dynamiczna wersja obrotowa:

Jeśli masz nieznaną liczbę kolumn (Paul, John, Tim, Eric w twoim przykładzie), a następnie nieznaną liczbę kolorów do przekształcenia, możesz użyć dynamicznego sql, aby wygenerować listę do UNPIVOT a następnie 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)

Zobacz SQL Fiddle z demonstracją

Wersja dynamiczna wysyła zapytania zarówno do yourtable a następnie sys.columns tabela do generowania listy elementów do UNPIVOT i PIVOT . Jest to następnie dodawane do ciągu zapytania do wykonania. Plusem wersji dynamicznej jest to, że masz zmieniającą się listę colors i/lub names to wygeneruje listę w czasie wykonywania.

Wszystkie trzy zapytania dadzą ten sam wynik:

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sprawdź, czy obiekt jest tabelą, widokiem lub procedurą składowaną w SQL Server za pomocą funkcji OBJECTPROPERTY()

  2. Połącz PHP z MSSQL przez PDO ODBC

  3. Jak szybko napisać Select Query w SQL Server — SQL Server / TSQL Tutorial, część 108

  4. DATEPART() Przykłady w SQL Server

  5. Korzystanie ze schematów baz danych w SQL Server