Om het gewenste resultaat te krijgen, moet u eerst UNPIVOT
de gegevens en PIVOT the
DatePeriod`-waarden.
De UNPIVOT transformeert de meerdere kolommen van Transactions
, Customers
en Visits
in meerdere rijen. De andere antwoorden gebruiken een UNION ALL
draaien, maar SQL Server 2005 was het eerste jaar dat de UNPIVOT
functie werd ondersteund.
De vraag om het draaien van de gegevens ongedaan te maken is:
select dateperiod,
col, value
from transactions
unpivot
(
value for col in (Transactions, Customers, Visits)
) u
Zie Demo . Dit transformeert uw huidige kolommen in meerdere rijen, zodat de gegevens er als volgt uitzien:
| DATEPERIOD | COL | VALUE |
-------------------------------------
| Jan 2012 | Transactions | 100 |
| Jan 2012 | Customers | 50 |
| Jan 2012 | Visits | 150 |
| Feb 2012 | Transactions | 200 |
Omdat de gegevens nu in rijen staan, kunt u de PIVOT
. toepassen functie naar de DatePeriod
kolom:
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;
Zie SQL Fiddle met demo .
Als u een onbekend aantal datumperiodes heeft, gebruikt u dynamische 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)
Zie SQL Fiddle met demo . Beide geven het resultaat:
| COL | JAN 2012 | FEB 2012 | MAR 2012 |
-------------------------------------------------
| Transactions | 100 | 200 | 300 |
| Customers | 50 | 100 | 200 |
| Visits | 150 | 300 | 600 |