【问题标题】:Using PIVOT to Flip Data from Wide to Tall使用 PIVOT 将数据从宽翻转到高
【发布时间】:2013-01-09 23:49:24
【问题描述】:

我有一张相当宽的桌子,我想把它改成高的。数据目前是这样的:

VEND   YEAR   I1_DOLS   I1_QTY   I2_DOLS   I2_QTY   I3_DOLS   I3_QTY ...
1234   2011   101587    508      203345    334      105938    257
1234   2012   257843    587      235883    247      178475    456
1011   2010   584737    432      587274    356      175737    563
1011   2011   517774    356      483858    456      481785    354

我想将其转换为如下所示的表格:

VEND   YEAR   MONTH   DOLS     QTY
1234   2011   1       101587   508
1234   2011   2       203345   334
1234   2011   3       105938   257
1234   2012   1       257843   587
1234   2012   2       235883   247
.
.
.

我认为 PIVOT 是我需要的,但我似乎无法弄清楚。

【问题讨论】:

    标签: sql sql-server-2008 tsql pivot unpivot


    【解决方案1】:

    您可以使用CROSS APPLY (VALUES)unpivot 数据。这是一篇文章来解释这是如何完成的:

    http://www.sqlservercentral.com/articles/CROSS+APPLY+VALUES+UNPIVOT/91234/

    基本上代码是:

    SELECT vend,
      year,
      month,
      dols, 
      qty
    FROM YourTable t
    CROSS APPLY 
    (
        VALUES
            (1, I1_DOLS, I1_QTY),
            (2, I2_DOLS, I2_QTY),
            (3, I3_DOLS, I3_QTY)
    ) x (month, dols, qty);
    

    SQL Fiddle with Demo

    或者您可以使用UNION ALL 查询:

    select vend, year, 1 month, [I1_DOLS] Dols, [I1_QTY] Qty
    from yourtable
    union all
    select vend, year, 2 month, [I2_DOLS] Dols, [I2_QTY] Qty
    from yourtable
    union all
    select vend, year, 3 month, [I3_DOLS] Dols, [I3_QTY] Qty
    from yourtable
    

    SQL Fiddle with Demo

    或者您甚至可以同时应用 UNPIVOTPIVOT 函数来转换数据:

    select *
    from
    (
      select vend,
        year,
        replace(replace(replace(col, 'I', ''), '_Dols', ''), '_Qty', '') month,
        case when col like '%Dols%' then 'dols' else 'qty' end col_name,
        value
      from 
      (
        select vend, year, [I1_DOLS], [I1_QTY], [I2_DOLS], [I2_QTY], [I3_DOLS], [I3_QTY]
        from yourtable
      ) src
      unpivot
      (
        value
        for col in ([I1_DOLS], [I1_QTY], [I2_DOLS], [I2_QTY], [I3_DOLS], [I3_QTY])
      ) un
    ) unp
    pivot
    (
      max(value)
      for col_name in (dols, qty)
    ) piv
    

    SQL Fiddle with Demo

    所有三个都会给出相同的结果:

    | VEND | YEAR | MONTH |   DOLS | QTY |
    --------------------------------------
    | 1234 | 2011 |     1 | 101587 | 508 |
    | 1234 | 2011 |     2 | 203345 | 334 |
    | 1234 | 2011 |     3 | 105938 | 257 |
    | 1234 | 2012 |     1 | 257843 | 587 |
    | 1234 | 2012 |     2 | 235883 | 247 |
    | 1234 | 2012 |     3 | 178475 | 456 |
    | 1011 | 2010 |     1 | 584737 | 432 |
    | 1011 | 2010 |     2 | 587274 | 356 |
    | 1011 | 2010 |     3 | 175737 | 563 |
    | 1011 | 2011 |     1 | 517774 | 356 |
    | 1011 | 2011 |     2 | 483858 | 456 |
    | 1011 | 2011 |     3 | 481785 | 354 |
    

    【讨论】:

    • 您的 CROSS APPLY 建议太棒了!看起来很简单,我不敢相信我从来没有想过这种技术。
    • @AndriyM 谢谢,我从 Cade Roux 的回答中学到了技巧 -- stackoverflow.com/questions/13591818/…
    • 嘿,我已经看过(并投票)了!我是一个多么健忘的人……但还是谢谢你们:)
    猜你喜欢
    • 2019-12-02
    • 1970-01-01
    • 2023-03-18
    • 2011-01-16
    • 1970-01-01
    • 2020-12-13
    • 2022-11-02
    • 2012-03-18
    • 1970-01-01
    相关资源
    最近更新 更多