多个案例SQL查询将单行检索为多列

时间:2017-04-26 20:47:28

标签: sql oracle

表:

ID VT_Type1 Vt_type2 VT_Type3 Status_1 Status_2 Status_3 Date_1 Date_2 Date_3
 1       -1       -1        0 X        Y        Z        04/12  05/12  06/12
 2       -1       -1       -1 A        B        C        06/12  07/12  07/10

预期输出

Id Type Status Date
1   1    X     04/12
1   2    Y     05/12
2   1    A     06/12
2   2    B     07/12
2   3    C     07/10

如果type为-1,则应将对应的status和date列作为一行检索。如上例所示,ID 1 type1为-1,type2为-1,因此2必须转换为2行,类型3为0,因此不予考虑。当我在网上看到例子时,我会看到要使用的案例但不确定如何使用以满足我的需求。

2 个答案:

答案 0 :(得分:1)

对表格进行三次查询,每种类型一次:

select id, 1 as type, status_1 as status, date_1 as "date" from mytable where VT_Type1 = -1
union all
select id, 2 as type, status_2 as status, date_2 as "date" from mytable where VT_Type2 = -1
union all
select id, 3 as type, status_3 as status, date_3 as "date" from mytable where VT_Type3 = -1

答案 1 :(得分:1)

在Oracle 11.1及更高版本中,您可以使用UNPIVOT运算符。如果您拥有大量数据,这将显着改善执行时间,因为它只需要读取一次表,而不是任何UNION ALL方法的三次。

我将列名(在输出中)从date更改为dt,因为DATE是Oracle中的保留字。 type并不是更好(它是一个关键字但不保留);最好也避免它。我在创建测试数据时也将日期视为字符串,但它与日期的工作方式相同。

with子句不是解决方案的一部分(不要盲目地复制并粘贴查询);我添加它只是为了测试目的。

with
     test_data ( ID, VT_Type1, Vt_type2, VT_Type3, Status_1, Status_2, Status_3, 
                                                         Date_1, Date_2, Date_3 ) as (
       select 1, -1, -1,  0, 'X', 'Y', 'Z', '04/12', '05/12', '06/12' from dual union all
       select 2, -1, -1, -1, 'A', 'B', 'C', '06/12', '07/12', '07/10' from dual
     )
select  id, type, status, dt
from    test_data
unpivot ( (vt_type, status, dt) for type in ( (vt_type1, status_1, date_1) as 1,
                                              (vt_type2, status_2, date_2) as 2,
                                              (vt_type3, status_3, date_3) as 3
                                            )
        )
where   vt_type != 0
;

ID  TYPE  STATUS  DT
--  ----  ------  -----
 1     1  X       04/12
 1     2  Y       05/12
 2     1  A       06/12
 2     2  B       07/12
 2     3  C       07/10