在SQL Server 2005中将列显示为行 [英] Displaying Columns as Rows in SQL Server 2005
问题描述
我已经阅读了数十种与拟提出的换位问题类似的解决方案,但奇怪的是,没有一个能够完全反映出我的问题.我只是试图将行翻转为简单的仪表板类型数据集中的列.
I have read dozens of solutions to similar transposition problems as the one I am about to propose but oddly none that exactly mirrors my issue. I am simply trying to flip my rows to columns in a simple dashboard type data set.
从各种交易表中提取数据时,数据看起来像这样:
The data when pulled from various transaction tables looks like this:
DatePeriod PeriodNumberOverall Transactions Customers Visits
'Jan 2012' 1 100 50 150
'Feb 2012' 2 200 100 300
'Mar 2012' 3 300 200 600
并且我希望能够生成以下内容:
and I want to be able to generate the following:
Jan 2012 Feb 2012 Mar 2012
Transactions 100 200 300
Customers 50 100 200
Visits 150 300 600
这些指标将是静态的(交易,客户和访问),而日期段将是动态的(即-随着月份的增加,还会增加).
The metrics will be static (Transactions, Customers and Visits), but the date periods will be dynamic (IE - more added as months go by).
再次,我准备了许多利用数据透视,取消透视,存储过程,UNION ALL等的示例,但是在我不进行任何聚合的情况下,什么也没做,只是从字面上移置了整个输出.我还发现在Visual Studio 2005中使用带有嵌入式列表的矩阵可以轻松实现此目的,但是我无法将最终输出导出到excel,这是必需的.任何帮助将不胜感激.
Again, I have ready many examples leveraging pivot, unpivot, store procedures, UNION ALLs, etc, but nothing where I am not doing any aggregating, just literally transposing the whole output. I have also found an easy way to do this in Visual Studio 2005 using a matrix with an embedded list, but I can't export the final output to excel which is a requirement. Any help would be greatly appreciated.
推荐答案
要获得所需结果,您需要先UNPIVOT
数据,然后PIVOT the
DatePeriod`值.
In order to get the result that you want you need to first UNPIVOT
the data and then PIVOT the
DatePeriod` Values.
UNPIVOT将Transactions
,Customers
和Visits
的多列转换为多行.其他答案是使用UNION ALL
取消透视,但是SQL Server 2005是支持UNPIVOT
功能的第一年.
The UNPIVOT will transform the multiple columns of Transactions
, Customers
and Visits
into multiple rows. The other answers are using a UNION ALL
to unpivot but SQL Server 2005 was the first year the UNPIVOT
function was supported.
取消数据透视表的查询是:
The query to unpivot the data is:
select dateperiod,
col, value
from transactions
unpivot
(
value for col in (Transactions, Customers, Visits)
) u
请参见演示.这会将您当前的列转换为多行,因此数据如下所示:
See Demo. This transforms your current columns into multiple rows, so the data looks like the following:
| DATEPERIOD | COL | VALUE |
-------------------------------------
| Jan 2012 | Transactions | 100 |
| Jan 2012 | Customers | 50 |
| Jan 2012 | Visits | 150 |
| Feb 2012 | Transactions | 200 |
现在,由于数据在行中,因此可以将PIVOT
函数应用于DatePeriod
列:
Now, since the data is in rows, you can apply the PIVOT
function to the DatePeriod
column:
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;
请参见带有演示的SQL小提琴.
如果日期周期的数量未知,则将使用动态SQL:
If you have an unknown number of date period's then you will use dynamic 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)
请参见带有演示的SQL小提琴.两者都会给出结果:
See SQL Fiddle with Demo. Both will give the result:
| COL | JAN 2012 | FEB 2012 | MAR 2012 |
-------------------------------------------------
| Transactions | 100 | 200 | 300 |
| Customers | 50 | 100 | 200 |
| Visits | 150 | 300 | 600 |
这篇关于在SQL Server 2005中将列显示为行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!