【问题标题】:How to PIVOT Column Headers - SQL Data如何透视列标题 - SQL 数据
【发布时间】:2014-01-29 22:10:38
【问题描述】:

我有一个需要旋转的数据集视图,其中 AMC1、AMC2 和 AMC3 的列标题将成为 LOB 下的行。这是原始的示例:

 Qtr    Year    BU  BU_Description  P2A_Line       AMC1  AMC2   AMC3
 Q3 2013    B52100  52100 - UFC      L1_1          203    17     7
 Q3 2013    B52100  52100 - UFC      L1_2          -      -      -   
 Q3 2013    B52100  52100 - UFC      L1_3          123    113    -   

这是最终结果的示例:

 Qtr    Year    BU  BU_Description   LOB     L1_1   L1_2    PL1_3
  Q3    2013    B52100  52100 - UFC  AMC1    203     -       123 
  Q3    2013    B52100  52100 - UFC  AMC2    17      -       113 
  Q3    2013    B52100  52100 - UFC  AMC3    7       -       -   

有没有人有一个简单且相对容易的方法来做到这一点?那里的例子有太多的变量来得出答案。任何帮助将不胜感激?

【问题讨论】:

  • 您使用的是哪个 DBMS?后格雷斯?甲骨文?
  • @a_horse_with_no_name SQL Server 管理工作室
  • 那不是 DBMS,那是客户端工具 - 但由于它只支持 Microsoft SQL Server,我猜你正在使用它。
  • 什么版本的sql server?

标签: sql-server sql-server-2008-r2 pivot


【解决方案1】:

有几种不同的方法可以获得结果,通过使用带有 CASE 表达式的聚合函数,使用 PIVOT 函数 - 但在实施这些方法之前,您首先需要查看对多列数据进行反透视 - @ 987654325@、AMC2AMC3

反透视的过程将您的多列转换为行。可以使用 unpivot 函数,也可以使用CROSS APPLY 转换数据:

select qtr, year, bu, bu_description, p2a_line,
  lob, value
from yourtable
cross apply
(
  select 'amc1', amc1 union all
  select 'amc2', amc2 union all
  select 'amc3', amc3
) c (lob, value);

SQL Fiddle with Demo。一旦数据采用这种格式,您就可以将 P2A_Line 值转换为列。

使用带有 CASE 表达式的聚合函数,查询将是:

select qtr, year, bu, bu_description,
  lob, 
  max(case when p2a_line = 'L1_1' then value end) L1_1,
  max(case when p2a_line = 'L1_2' then value end) L1_2,
  max(case when p2a_line = 'L1_3' then value end) L1_3
from 
(
  select qtr, year, bu, bu_description, p2a_line,
    lob, value
  from yourtable
  cross apply
  (
    select 'amc1', amc1 union all
    select 'amc2', amc2 union all
    select 'amc3', amc3
  ) c (lob, value)
) d
group by qtr, year, bu, bu_description, lob;

SQL Fiddle with Demo

在 SQL Server 2005+ 中,您可以使用 PIVOT 函数:

select qtr, year, bu, bu_description,
  lob, L1_1, L1_2, L1_3
from 
(
  select qtr, year, bu, bu_description, p2a_line,
    lob, value
  from yourtable
  cross apply
  (
    select 'amc1', amc1 union all
    select 'amc2', amc2 union all
    select 'amc3', amc3
  ) c (lob, value)
) d
pivot
(
  max(value)
  for p2a_line in (L1_1, L1_2, L1_3)
) piv;

SQL Fiddle with Demo

最后,如果您有未知数量的 p2a_line 值,那么您可以使用动态 SQL:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT  ',' + QUOTENAME(P2A_Line) 
                    from yourtable
                    group by P2A_Line
                    order by P2A_Line
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = N'SELECT qtr, year, bu, bu_description, lob,' + @cols + N' 
            from 
            (
              select qtr, year, bu, bu_description, p2a_line,
                lob, value
              from yourtable
              cross apply
              (
                select ''amc1'', amc1 union all
                select ''amc2'', amc2 union all
                select ''amc3'', amc3
              ) c (lob, value)
            ) x
            pivot 
            (
                max(value)
                for p2a_line in (' + @cols + N')
            ) p '

execute sp_executesql @query;

SQL Fiddle with Demo

所有版本都给出结果:

| QTR | YEAR |     BU | BU_DESCRIPTION |  LOB | L1_1 |   L1_2 |   L1_3 |
|-----|------|--------|----------------|------|------|--------|--------|
|  Q3 | 2013 | B52100 |    52100 - UFC | amc1 |  203 | (null) |    123 |
|  Q3 | 2013 | B52100 |    52100 - UFC | amc2 |   17 | (null) |    113 |
|  Q3 | 2013 | B52100 |    52100 - UFC | amc3 |    7 | (null) | (null) |

【讨论】:

    猜你喜欢
    • 2016-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 1970-01-01
    相关资源
    最近更新 更多