在 Oracle 中取消透视到多个列



>我有一个表格如下:

EVENT_ID    NUM_A    NUM_A_SRC    NUM_B    NUM_B_SRC
1           5        Yelp         4        Google
2           3        Yelp         1        Google

我需要将其转换为以下格式:

EVENT_ID    SRC       RANK
1           Yelp      5
1           Google    4
2           Yelp      3
2           Google    1

我一生都无法弄清楚如何取消透视并使结果集为多列。谁能帮忙?有关可重现的示例,请参见下文:

CREATE TABLE EXAMPLE(
EVENT_ID NUMBER,
NUM_A NUMBER,
NUM_A_SRC VARCHAR2(10),
NUM_B NUMBER,
NUM_B_SRC VARCHAR2(10)
); 
INSERT INTO EXAMPLE (EVENT_ID, NUM_A, NUM_A_SRC, NUM_B, NUM_B_SRC)
VALUES
(1, 5, 'Yelp', 4, 'Google');
INSERT INTO EXAMPLE (EVENT_ID, NUM_A, NUM_A_SRC, NUM_B, NUM_B_SRC)
VALUES
(2, 3, 'Yelp', 1, 'Google');
SELECT * FROM EXAMPLE;

在 Oracle 中,最简单的方法可能是union all

select event_id, num_a_src src, num_a rnk from example
union all
select event_id, num_b_src, num_b from example

请注意,rank是一个语言关键字(有一个窗口函数使用该名称( - 我在查询中将其重命名为rnk

DB小提琴上的演示

EVENT_ID |SRC |嗤嗤 -------: |:----- |--:  1 |耶尔普 |  5  2 |耶尔普 |  3  1 |谷歌 |  4  2 |谷歌 |  1

对源表进行一次扫描:

with s (event_id, num_a, num_a_src, num_b, num_b_src) as (
select 1, 5, 'Yelp', 4, 'Google' from dual union all
select 2, 3, 'Yelp', 1, 'Google' from dual)
select event_id,
decode(rn, 1, num_a    , 2, num_b    ) rank,
decode(rn, 1, num_a_src, 2, num_b_src) num_src
from s, (select rownum rn from dual connect by level <= 2)
order by rank desc;
EVENT_ID       RANK NUM_SRC
---------- ---------- -------
1          5 Yelp
1          4 Google
2          3 Yelp
2          1 Google

最新更新