use*_*794 6 sql t-sql pivot sql-server-2005
我已经阅读了几十个解决类似换位问题的解决方案,就像我即将提出的问题一样,但奇怪的是没有一个能够完全反映我的问题.我只是想在一个简单的仪表板类型数据集中将我的行翻转到列.
从各种事务表中提取的数据如下所示:
DatePeriod PeriodNumberOverall Transactions Customers Visits
'Jan 2012' 1 100 50 150
'Feb 2012' 2 200 100 300
'Mar 2012' 3 300 200 600
Run Code Online (Sandbox Code Playgroud)
我希望能够生成以下内容:
Jan 2012 Feb 2012 Mar 2012
Transactions 100 200 300
Customers 50 100 200
Visits 150 300 600
Run Code Online (Sandbox Code Playgroud)
指标将是静态的(交易,客户和访问),但日期周期将是动态的(IE - 随着月份的增加而增加).
再一次,我已经准备好了许多利用pivot,unpivot,存储过程,UNION ALLs等的例子,但没有任何我没有做任何聚合的事情,只是字面上转换整个输出.我还在Visual Studio 2005中使用带有嵌入列表的矩阵找到了一种简单的方法,但我无法将最终输出导出到excel,这是一项要求.任何帮助将不胜感激.
为了获得您想要的结果,您需要首先获取UNPIVOT数据,然后获取PIVOT theDatePeriod` 值。
UNPIVOT 会将Transactions,Customers和的多列转换Visits为多行。其他答案是使用 a来取消透视,但 SQL Server 2005 是支持UNION ALL该功能的第一年。UNPIVOT
取消透视数据的查询是:
select dateperiod,
col, value
from transactions
unpivot
(
value for col in (Transactions, Customers, Visits)
) u
Run Code Online (Sandbox Code Playgroud)
请参阅演示。这会将当前列转换为多行,因此数据如下所示:
| DATEPERIOD | COL | VALUE |
-------------------------------------
| Jan 2012 | Transactions | 100 |
| Jan 2012 | Customers | 50 |
| Jan 2012 | Visits | 150 |
| Feb 2012 | Transactions | 200 |
Run Code Online (Sandbox Code Playgroud)
现在,由于数据位于行中,因此您可以将该PIVOT函数应用于DatePeriod列:
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;
Run Code Online (Sandbox Code Playgroud)
请参阅SQL Fiddle 演示。
如果您的日期周期数量未知,那么您将使用动态 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)
Run Code Online (Sandbox Code Playgroud)
请参阅SQL Fiddle 演示。两者都会给出结果:
| COL | JAN 2012 | FEB 2012 | MAR 2012 |
-------------------------------------------------
| Transactions | 100 | 200 | 300 |
| Customers | 50 | 100 | 200 |
| Visits | 150 | 300 | 600 |
Run Code Online (Sandbox Code Playgroud)