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

Wyświetlanie kolumn jako wierszy w SQL Server 2005

Aby uzyskać żądany wynik, musisz najpierw UNPIVOT dane, a następnie PIVOT the Wartości daty i okresu.

UNPIVOT przekształci wiele kolumn Transactions , Customers i Visits w wielu rzędach. Pozostałe odpowiedzi używają UNION ALL do unpivot, ale SQL Server 2005 był pierwszym rokiem UNPIVOT funkcja była obsługiwana.

Zapytanie w celu odwrócenia danych to:

select dateperiod,
  col, value
from transactions
unpivot
(
  value for col in (Transactions, Customers, Visits)
) u

Zobacz Demo . Spowoduje to przekształcenie bieżących kolumn w wiele wierszy, dzięki czemu dane wyglądają następująco:

| DATEPERIOD |          COL | VALUE |
-------------------------------------
|   Jan 2012 | Transactions |   100 |
|   Jan 2012 |    Customers |    50 |
|   Jan 2012 |       Visits |   150 |
|   Feb 2012 | Transactions |   200 |

Teraz, ponieważ dane są w wierszach, możesz zastosować PIVOT the funkcji do DatePeriod kolumna:

select col, [Jan 2012], [Feb 2012], [Mar 2012]
from
(
  select dateperiod,
    t.col, value, c.SortOrder
  from
  (
    select dateperiod,
      col, value
    from transactions
    unpivot
    (
      value for col in (Transactions, Customers, Visits)
    ) u
  ) t
  inner join
  (
    select 'Transactions' col, 1 SortOrder
    union all
    select 'Customers' col, 2 SortOrder
    union all
    select 'Visits' col, 3 SortOrder
   ) c
    on t.col = c.col
) d
pivot
(
  sum(value)
  for dateperiod in ([Jan 2012], [Feb 2012], [Mar 2012])
) piv
order by SortOrder;

Zobacz SQL Fiddle z wersją demonstracyjną .

Jeśli masz nieznaną liczbę okresów dat, użyjesz dynamicznego SQL:

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

select @cols = STUFF((SELECT ',' + QUOTENAME(dateperiod) 
                    from transactions
                    group by dateperiod, PeriodNumberOverall
                    order by PeriodNumberOverall
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT col, ' + @cols + ' 
             from 
             (
                select dateperiod,
                  t.col, value, c.SortOrder
                from
                (
                  select dateperiod,
                    col, value
                  from transactions
                  unpivot
                  (
                    value for col in (Transactions, Customers, Visits)
                  ) u
                ) t
                inner join
                (
                  select ''Transactions'' col, 1 SortOrder
                  union all
                  select ''Customers'' col, 2 SortOrder
                  union all
                  select ''Visits'' col, 3 SortOrder
                 ) c
                  on t.col = c.col
            ) x
            pivot 
            (
                sum(value)
                for dateperiod in (' + @cols + ')
            ) p 
            order by SortOrder'

execute(@query)

Zobacz SQL Fiddle z wersją demonstracyjną . Oba dadzą wynik:

|          COL | JAN 2012 | FEB 2012 | MAR 2012 |
-------------------------------------------------
| Transactions |      100 |      200 |      300 |
|    Customers |       50 |      100 |      200 |
|       Visits |      150 |      300 |      600 |


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak znaleźć trzecią lub nᵗʰ maksymalną pensję z tabeli wynagrodzeń?

  2. Jak mogę dodać dokładnie 1 milisekundę?

  3. Wdrażanie stronicowania za pomocą OFFSET FETCH NEXT w SQL Server

  4. Naśladuj group_concat() w połączeniu z GROUP BY

  5. Jak usunąć kolumnę z zależnościami obiektów w SQL Server 2008?