【问题标题】:Oracle - Connect By PriorOracle - 按先验连接
【发布时间】:2021-08-11 03:39:08
【问题描述】:

我知道我必须在此查询中使用 CONNECT BY PRIOR,但我不确定如何实现它。

我们有购买每月订阅的客户,这些客户每月都会自动续订。我们有一个日志表,可以显示您当前的订单 ID 是什么,以及您之前的订单 ID 是什么。所以,表记录可能是这样的:

CUSTOMER ID: 1     ORDER ID: 123   PREV_ORDER_ID:       STATUS: Complete
CUSTOMER ID: 1     ORDER ID: 456   PREV_ORDER_ID: 123   STATUS: Complete
CUSTOMER ID: 1     ORDER ID: 789   PREV_ORDER_ID: 456   STATUS: Complete
CUSTOMER ID: 1     ORDER ID: 888   PREV_ORDER_ID: 789   STATUS: Complete
CUSTOMER ID: 1     ORDER ID: 999   PREV_ORDER_ID: 888   STATUS: Active

我正在计算有多少客户连续订阅了至少 13 个月,与最近一次订阅没有间隔的客户将处于“有效”状态。如果订阅中断,则 PREV_ORDER_ID 将为 NULL。

希望在查询中执行此操作,而不必为其编写匿名块。

非常感谢!

【问题讨论】:

    标签: oracle connect hierarchical


    【解决方案1】:

    您可以这样做(使用您的实际表名和列名,而不是查询中的 with 子句,您应该删除它)。请注意,分层递归从末尾开始(从'Active' 状态)并向后进行;在我的查询中,我在第 4 级停止它,因为我不想写足够的行来达到第 13 级。当然,您必须在 where 子句中将 4 替换为 13。

    with
      test_data (customer_id, order_id, prev_order_id, status) as (
        select 1, 123, null, 'Complete' from dual union all
        select 1, 456,  123, 'Complete' from dual union all
        select 1, 789,  456, 'Complete' from dual union all
        select 1, 888,  789, 'Complete' from dual union all
        select 1, 999,  888, 'Active'   from dual union all
        select 2, 100, null, 'Complete' from dual union all
        select 2, 200,  100, 'Active'   from dual union all
        select 5, 105, null, 'Complete' from dual union all
        select 5, 106,  105, 'Complete' from dual union all
        select 5, 205, null, 'Complete' from dual union all
        select 5, 206,  205, 'Active'   from dual
      )
    select  customer_id
    from    test_data
    where   level = 4
    start   with status = 'Active'
    connect by customer_id = prior customer_id and order_id = prior prev_order_id
    ;
    
    CUSTOMER_ID
    -----------
              1
    

    【讨论】:

    • 看起来它正在完成这项工作。非常感谢!
    【解决方案2】:

    需要更多的数据和测试。

    也许对你有帮助

    CREATE TABLE CUSTOMER_LOG
    (
    CUSTOMER_ID number(5),
    ORDER_ID number(5),
    PREV_ORDER_ID number(5),
    STATUS VARCHAR(50)
    );
    
    INSERT INTO CUSTOMER_LOG(CUSTOMER_ID,ORDER_ID,PREV_ORDER_ID,STATUS) values (1,123,NULL, 'Complete');
    INSERT INTO CUSTOMER_LOG(CUSTOMER_ID,ORDER_ID,PREV_ORDER_ID,STATUS) values (1,456,123, 'Complete');
    INSERT INTO CUSTOMER_LOG(CUSTOMER_ID,ORDER_ID,PREV_ORDER_ID,STATUS) values (1,789,456, 'Complete');
    INSERT INTO CUSTOMER_LOG(CUSTOMER_ID,ORDER_ID,PREV_ORDER_ID,STATUS) values (1,888,789, 'Complete');
    INSERT INTO CUSTOMER_LOG(CUSTOMER_ID,ORDER_ID,PREV_ORDER_ID,STATUS) values (1,999,888, 'Active');
    
    Select
    l.*,
    (
    select count(*)
    from CUSTOMER_LOG s
    where s.customer_id=1
    start with s.ORDER_ID=l.ORDER_ID
    connect by s.ORDER_ID= prior s.PREV_ORDER_ID   
    ) QTDE
    from CUSTOMER_LOG l
    where l.status='Active'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-04
      • 2019-03-24
      • 1970-01-01
      • 1970-01-01
      • 2022-01-03
      相关资源
      最近更新 更多