【问题标题】:Identifying start and end of period covered - oracle 10g sql识别所涵盖期间的开始和结束 - oracle 10g sql
【发布时间】:2012-10-06 09:50:31
【问题描述】:

我的数据如下所示:

        ID      FROM        TO          START_CODE      END_CODE    TYPE
        A       01/01/2012  02/02/2012  P               E           1
        A       12/03/2011  01/01/2012  P               X           1
        A       01/01/2011  12/03/2011  S               X           2

        A       01/01/2010  02/02/2010  P               E           2
        A       12/03/2010  01/01/2010  P               X           4
        A       01/01/2009  12/03/2009  S               X           1

基本上,这是针对一位客户的信息。 end_code 'e' 表示护理期的结束, start_code 's' 表示护理期的开始。 “p”的开始代码表示日期是一个延续,“x”的结束代码也是如此。我希望能够返回的是如下所示的数据:

        ID      START       END             Types
        A       01/01/2011  02/02/2012      2,1,1
        A       01/01/2009  02/02/2010      1,4,2

第一个表的查询看起来与此类似(仅作为示例),但是,我有兴趣返回多个客户,而不仅仅是“A”。

        SELECT
        A.ID,
        A.FROM,
        A.TO,
        A.START_CODE,
        A.END_CODE,
                       A.Type

        WHERE
        A.ID = 'A'

我过去曾使用 xmlagg 来实现类似的事情(即在一个单元格中列出信息),但它实际上是为每个客户端识别单独的开始和结束日期,然后返回我正在努力的类型序列和。供参考,我的oracle版本是10g,10.2.0.5.0。

感谢您的宝贵时间,感谢您的指点或帮助。

编辑后包含 A.B.Cade 的建议如下:

        SELECT
        t3.MOV_PER_GRO_ID,
        t3.f,
        t3.MOV_END_DATE,
        t3.types,
        LENGTH(REGEXP_REPLACE(t3.types,'[^,]')) as "Count"
        FROM(

        SELECT 
        sys_connect_by_path(t2.MOV_2000_PLACEMENT_TYPE,',') types,
        connect_by_root(t2.MOV_START_DATE) f, 
        t2.MOV_START_DATE,        
        t2.MOV_END_DATE,        
        connect_by_isleaf is_leaf, 
        t2.MOV_PER_GRO_ID 
        FROM (SELECT t.*,
        lag(t.MOV_START_DATE) over (ORDER BY t.MOV_PER_GRO_ID, t.MOV_START_DATE) nfrom
        FROM O_MOVEMENTS t
        WHERE t.MOV_PER_GRO_ID IN ('A','B'))t2 
        START 
        WITH 
        t2.MOV_2000_START_REASON = 'S'
        CONNECT BY   
        PRIOR t2.MOV_START_DATE = t2.nfrom
        AND PRIOR t2.MOV_PER_GRO_ID =  t2.MOV_PER_GRO_ID 
        AND t2.MOV_2000_START_REASON IN ('P'))t3
        where t3.is_leaf=1

根据 ABCade 的解决方案进行了更新。经过一些调整(再次感谢 ABCade),它似乎可以正常工作了。

【问题讨论】:

    标签: sql oracle list date oracle10g


    【解决方案1】:

    试试:

    SELECT  t3."ID", t3.f "start", t3."TO" "end", t3.types
    FROM (
    SELECT sys_connect_by_path(t2."TYPE",',') types,
           connect_by_root(t2."FROM") f,
           t2."FROM",
           t2."TO",
           connect_by_isleaf is_leaf ,
    t2."ID"
    FROM (
      SELECT t.*, lag(t."FROM") over (ORDER BY t."FROM") nfrom
        FROM table1 t
       WHERE t."ID" = 'A'
      ) t2
    START WITH t2."START_CODE" = 'S'
    CONNECT BY   PRIOR t2."FROM" = t2.nfrom  AND t2."START_CODE" = 'P') t3
    WHERE is_leaf=1
    

    Here 是一个小提琴
    Here 是另一个小提琴(在看到你的评论和更新之后)

    【讨论】:

    • 感谢您,我以前从未见过使用 sys_connect_by_path 的查询,但我会尽快尝试一下。非常感谢。
    • @bawpie,如果没有你的表格定义和一些真实的数据样本,很难说,但我的猜测是它与我所做的一些假设有关:1)期间可能有 gups(这个这就是为什么我使用lag 而不能信任prior from = to,2) 期间没有重叠。我没有考虑使用“ID”字段。如果假设(2)是正确的,但仅适用于每个“ID”,那么在最内部的选择中添加 WHERE t."ID"='A' 应该可以。
    • @ABCade - 谢谢,我现在可以使用一个 ID(查询中的更新代码)。如果我尝试在多个 id 上运行它,有时我会收到有关 ORA-01436: CONNECT BY loop in user data 的错误,连接中是否需要引用 ID 的内容?恐怕我不熟悉使用 connect by。
    • @ABCade - 将 id 添加到 lagg 的 orderby 中,现在它正在成功运行查询(请参阅上面的更新代码)。我需要检查结果,所以祈祷吧!
    • @ABCade - 这种变化产生了奇怪的结果,在某些情况下(但在其他情况下不是?),时期被分成单独的时期。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-30
    • 1970-01-01
    • 2021-09-19
    • 2019-11-02
    • 2021-07-05
    • 2011-07-10
    相关资源
    最近更新 更多