我有一张桌子,看起来像这样:
PK
)。我显然需要它。AA
,BB
和CC
有6个版本(最多AA5
,BB5
,CC5
)。所有这些都是字符串。
AA
,BB
和CC
彼此绑定:如果有AA
,则应BB
和{{1} }}。 CC
,AA
,BB
,CC
,AA2
,{{ 1}}未填写,BB2
,CC2
,AA3
已填满! 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
这可能吗?
答案 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) )
)
答案 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}}