Oracle查询将一些列迁移到一个

时间:2018-01-06 10:35:20

标签: sql oracle

我有一张桌子,看起来像这样:

  • 有一个主键(PK)。我显然需要它。
  • AABBCC有6个版本(最多AA5BB5CC5)。所有这些都是字符串。
    • AABBCC彼此绑定:如果有AA,则应BB和{{1} }}。
    • 必须不断填写:没有填充CCAABBCCAA2,{{ 1}}未填写,BB2CC2AA3已填满!
  • 还有其他专栏,但我不需要它们。

BB3

我想对查询做些什么:

  • 我需要CC3
  • 所有PK AA BB CC AA2 BB2 CC2 AA3 BB3 CC3 1 X Y Z D F G 2 Q W E 3 U I O P H K L R M都应放在名为PK的一列中。
  • 所有AA都应放在名为AAA的一列中。
  • 所有BB都应放在名为BBB的一列中。

CC

这可能吗?

3 个答案:

答案 0 :(得分:3)

您可以使用UNPIVOT

编辑:我原来的回答中没有JOIN,感谢@mathguy,我能够纠正它。

select pk,AAA,BBB,CCC FROM YOURTABLE 
UNPIVOT 
  ( (AAA,BBB,CCC) 
      FOR col in ( (aa, bb, cc), (aa2, bb2, cc2), (aa3, bb3, cc3) )
   ) 

DEMO

答案 1 :(得分:3)

使用UNION ALL运算符:

SELECT pk, aa As aaa,bb as bbb,cc as ccc 
FROM table1

UNION ALL

SELECT pk, aa2,bb2,cc2
FROM table1
WHERE aa2 IS NOT NULL

UNION ALL

SELECT pk, aa3,bb3,cc3
FROM table1
WHERE aa3 IS NOT NULL

演示:http://sqlfiddle.com/#!4/6a7487/4

| PK | AAA | BBB | CCC |
|----|-----|-----|-----|
|  1 |   D |   F |   G |
|  1 |   X |   Y |   Z |
|  2 |   Q |   W |   E |
|  3 |   P |   H |   K |
|  3 |   L |   R |   M |
|  3 |   U |   I |   O |

答案 2 :(得分:1)

union all运算符之前,通过交叉连接到一个小表(单列,与列或列组一样多的行需要取消隐藏:在您的情况下,六个 - 或在简化的例子,三)。

这种方法的原因 - 与简单但效率低下的select t.pk, case h.lvl when 1 then aa when 2 then aa2 when 3 then aa3 end as aa, case h.lvl when 1 then bb when 2 then bb2 when 3 then bb3 end as bb, case h.lvl when 1 then cc when 2 then cc2 when 3 then cc3 end as cc from table1 t cross join ( select level as lvl from dual connect by level <= 3 ) h ; 方法相比 - 是你只需要读一次基表。

像这样:(&#34; table1&#34;是基表的名称)

where

注意:这也会产生aa,bb和cc为NULL的行(例如,aa3,bb3和cc3在基表中为null)。如果需要,可以通过将交叉连接包装在外部查询中并添加where aa is not null子句来删除它们,例如:unpivot

<强> UNPIVOT

以下是如何在Oracle 11.1及更高版本中完成此操作。可以在单个select pk, aa, bb, cc from table1 unpivot ( (aa, bb, cc) for rn in ( (aa, bb, cc), (aa2, bb2, cc2), (aa3, bb3, cc3) ) ); 操作中忽略列组,如下所示:

{{1}}