【问题标题】:Oracle SQL - Derive multiple rows from column combination of single rowOracle SQL - 从单行的列组合派生多行
【发布时间】:2019-02-12 15:34:33
【问题描述】:

我在 Oracle SQL DB 上有这样的数据:

personId  lastEvent currentEvent nextEvent
1         null      1            2
1         1         2            3
1         2         3            4
1         3         4            null

对于像这样的单行

personId  lastEvent currentEvent nextEvent
1         null      1            2

我想通过将事件列组合在一起并将这两行分类到特定的 currentEvent 来提取提取的两行。例如:

第 1 行

personId  lastEvent currentEvent nextEvent
1         null      1            2

结果 #1

personId  event1 event2 currentEvent
1         null   1      1
1         1      2      1  

第 2 行

personId  lastEvent currentEvent nextEvent
1         1         2            3

结果 #2

personId  event1 event2 currentEvent
1         1      2      2
1         2      3      2

等等…… 我知道子句 CONNECT BY 的存在,但我真的无法弄清楚获取这些结果的查询。

【问题讨论】:

    标签: sql oracle connect-by hierarchical-query


    【解决方案1】:

    这根本不是分层查询:您只想将每个输入行拆分为两个输出行并应用一些逻辑。

    执行拆分的一种简单方法是将您的表CROSS JOIN 转换为正好有两行的行源。

    例如,

    with input_data ( personId,  lastEvent, currentEvent, nextEvent) AS
    (
    SELECT 1, null, 1, 2     FROM DUAL UNION ALL
    SELECT 1, 1,    2, 3     FROM DUAL UNION ALL
    SELECT 1, 2,    3, 4     FROM DUAL UNION ALL
    SELECT 1, 3,    4, null  FROM DUAL )
    SELECT personId,
           decode(rn, 1, lastEvent, 2, currentEvent) event1,
           decode(rn, 1, currentEvent, 2, nextEvent) event2,
           currentEvent
    from input_data 
    CROSS JOIN ( SELECT rownum rn FROM DUAL CONNECT BY ROWNUM <= 2 ) r
    ORDER BY personId, currentEvent, rn;
    
    +----------+--------+--------+--------------+
    | PERSONID | EVENT1 | EVENT2 | CURRENTEVENT |
    +----------+--------+--------+--------------+
    |        1 |        |      1 |            1 |
    |        1 |      1 |      2 |            1 |
    |        1 |      1 |      2 |            2 |
    |        1 |      2 |      3 |            2 |
    |        1 |      2 |      3 |            3 |
    |        1 |      3 |      4 |            3 |
    |        1 |      3 |      4 |            4 |
    |        1 |      4 |        |            4 |
    +----------+--------+--------+--------------+
    

    【讨论】:

    • 非常感谢!可能我的sql知识有一些空白需要补上。
    【解决方案2】:

    这是执行此操作的一种方法。

    我没有为此使用分层查询。

    create table t(personId int,lastEvent int, currentEvent int, nextEvent int);
    
    insert into t values(1,null,1,2);
    insert into t values(1,1,2,3);
    insert into t values(1,2,3,4);
    insert into t values(1,3,4,null);
    
    
        select a.personId,case when b.rn=1 then 
                                a.lastEvent 
                           else a.currentEvent
                       end as event1
           ,case when b.rn=1 then 
                      a.currentEvent 
                 else a.nextEvent
             end as event2
           ,case when a.nextEvent is not null then 
                      a.currentEvent
            end as currentEvent       
      from t a
      join (select rownum as rn from all_objects where rownum<=2) b
        on case when a.nextEvent is not null then 2
                else 1
            end >=b.rn
    order by 1,4,3   
    
    
    +----------+--------+--------+--------------+
    | PERSONID | EVENT1 | EVENT2 | CURRENTEVENT |
    +----------+--------+--------+--------------+
    |        1 |     -  |      1 |            1 |
    |        1 |      1 |      2 |            1 |
    |        1 |      1 |      2 |            2 |
    |        1 |      2 |      3 |            2 |
    |        1 |      2 |      3 |            3 |
    |        1 |      3 |      4 |            3 |
    |        1 |      3 |      4 |           -  |
    +----------+--------+--------+--------------+
    

    【讨论】:

      猜你喜欢
      • 2023-03-09
      • 2013-12-31
      • 2020-02-06
      • 1970-01-01
      • 2022-11-30
      • 1970-01-01
      • 2020-07-01
      • 2015-11-18
      相关资源
      最近更新 更多