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 |