在SQL Server 2005中将列显示为行 [英] Displaying Columns as Rows in SQL Server 2005

查看:84
本文介绍了在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 theDatePeriod` Values.

UNPIVOT将TransactionsCustomersVisits的多列转换为多行.其他答案是使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆