使用 PIVOT 将数据从宽翻转到高 [英] Using PIVOT to Flip Data from Wide to Tall

查看:14
本文介绍了使用 PIVOT 将数据从宽翻转到高的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a table that is rather wide that I would like to convert to tall. The data currently resides like this:

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

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

I would like to convert this to a table that looks like this:

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 是我需要的,但我似乎无法弄清楚这一点.

I assume that a PIVOT is what I need, but I can't seem to figure this out.

推荐答案

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

You can unpivot the data using CROSS APPLY (VALUES). Here is an article to explain how this is done:

http://www.sqlservercentral.com/articles/CROSS+应用+值+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 查询:

Or you could use a UNION ALL query:

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 函数来转换数据:

Or you can even apply both the UNPIVOT and the PIVOT function to transform the data:

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.

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

All three will give the same result:

| 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 |

这篇关于使用 PIVOT 将数据从宽翻转到高的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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