简体   繁体   English

高效地将列转换为行

[英]Transposing Columns to Rows Efficiently

Can you please help me with this project? 你能帮我这个项目吗? I did research the prior asked questions, but they don't seem to address this unique situation. 我确实研究了先前提出的问题,但是它们似乎无法解决这种独特的情况。

Sample data: 样本数据:

 Member |    DOS    |  Dx1   |  Dx2  |  Dx3  | Dx4  | Dx5
 12345  | 1/1/2011  | 12142  | 12345 | 65657 | 5657 | 568
 56484  | 3/5/2011  | 568    | 56785 | 5695  | 575  | 168
 56872  | 2/12/2011 | 567    | 567   |

What I need to see is this: 我需要看的是:

 Member DOS DX Seq
 12345 1/1/2011 12142 Dx1
 12345 1/1/2011 12345 Dx2
 12345 1/1/2011 65657 Dx3

and so forth. 等等。 Only showing those Dx where not null- so for 56872, we'd only see Dx1 and Dx2, but for the other 2, we'd see records for all 5 Dx. 仅显示那些Dx不为空-因此对于56872,我们只会看到Dx1和Dx2,而对于其他2,我们将看到所有5个Dx的记录。

Is anyone able to help me? 有人可以帮助我吗? Thank you. 谢谢。

This type of data transformation is called an UNPIVOT . 这种数据转换称为UNPIVOT Unfortunately MySQL doesn't have an unpivot function but you can replicate the functionality a few different ways. 不幸的是,MySQL没有取消旋转功能,但是您可以通过几种不同的方式复制该功能。

You can use a UNION ALL query to convert each column value into rows: 您可以使用UNION ALL查询将每个列值转换为行:

select member, dos, dx, seq
from
(
  select member, dos, dx1 as dx, 'Dx1' as seq
  from yourtable
  union all
  select member, dos, dx2 as dx, 'Dx2' as seq
  from yourtable
  union all
  select member, dos, dx3 as dx, 'Dx3' as seq
  from yourtable
  union all
  select member, dos, dx4 as dx, 'Dx4' as seq
  from yourtable
  union all
  select member, dos, dx5 as dx, 'Dx5' as seq
  from yourtable
) d
where dx is not null
order by member, seq;

See SQL Fiddle with Demo . 请参阅带有演示的SQL Fiddle This method will get you the result but it might not be very efficient on larger tables. 此方法将为您提供结果,但在较大的表上可能效率不高。

Another method would be using a CROSS JOIN on a virtual table: 另一种方法是在虚拟表上使用CROSS JOIN:

select member, dos, dx, seq
from
(
  select t.member, t.dos, 
    case s.seq
      when 'Dx1' then dx1
      when 'Dx2' then dx2
      when 'Dx3' then dx3
      when 'Dx4' then dx4
      when 'Dx5' then dx5
    end DX,
    s.seq
  from yourtable t
  cross join
  (
    select 'Dx1' as seq union all
    select 'Dx2' as seq union all
    select 'Dx3' as seq union all
    select 'Dx4' as seq union all
    select 'Dx5' as seq
  ) s
) d
where dx is not null
order by member, seq;

See SQL Fiddle with Demo . 请参阅带有演示的SQL Fiddle Both give a result: 两者都给出结果:

| MEMBER |                             DOS |    DX | SEQ |
|--------|---------------------------------|-------|-----|
|  12345 |  January, 01 2011 00:00:00+0000 | 12142 | Dx1 |
|  12345 |  January, 01 2011 00:00:00+0000 | 12345 | Dx2 |
|  12345 |  January, 01 2011 00:00:00+0000 | 65657 | Dx3 |
|  12345 |  January, 01 2011 00:00:00+0000 |  5657 | Dx4 |
|  12345 |  January, 01 2011 00:00:00+0000 |   568 | Dx5 |

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM