【问题标题】:How to find records with recursively overlapping date ranges in Oracle DB如何在 Oracle DB 中查找具有递归重叠日期范围的记录
【发布时间】:2017-05-16 15:48:26
【问题描述】:

我有一张这样的桌子:

|身份证 |开始 |登 +--------+------------+---------- |脂肪1 | 2017 年 1 月 1 日 | 2017 年 1 月 31 日 |脂肪2 | 2017 年 1 月 2 日 | 28/02/2017 |脂肪3 | 2017 年 1 月 3 日 | 2017 年 3 月 31 日 |脂肪4 | 2017 年 1 月 4 日 | 2017 年 4 月 30 日 |脂肪5 | 2017 年 1 月 2 日 | 2017 年 3 月 31 日 |脂肪6 | 2017 年 1 月 1 日 | 28/02/2017 |脂肪7 | 2017 年 1 月 3 日 | 2017 年 4 月 30 日 |脂肪8 | 2017 年 1 月 6 日 | 2017 年 6 月 30 日 |脂肪9 | 2017 年 4 月 28 日 | 2017 年 2 月 5 日

给定一条记录,我想找到所有重叠的记录以及所有与重叠记录重叠的记录。

例如搜索 fat7 的重叠记录应该返回 fat5 (overlaps fat7) fat4 (overlaps fat7) fat3 (overlaps fat7) fat2 (*overlaps fat5) fat6 (*overlaps fat5) fat1 (**overlaps fat6)

创建数据集:

创建表 zz_fatt ( id varchar2(100) 主键, 开始日期, 结束日期); 插入 zz_fatt (id, dstart, dend) 值 ('fat7', to_date('03/01/2017', 'mm/dd/yyyy'), to_date('04/30/2017', 'mm/dd/ yyyy')); 插入 zz_fatt (id, dstart, dend) 值 ('fat1', to_date('01/01/2017', 'mm/dd/yyyy'), to_date('01/31/2017', 'mm/dd/ yyyy')); 插入 zz_fatt (id, dstart, dend) 值 ('fat2', to_date('02/01/2017', 'mm/dd/yyyy'), to_date('02/28/2017', 'mm/dd/ yyyy')); 插入 zz_fatt (id, dstart, dend) 值 ('fat3', to_date('03/01/2017', 'mm/dd/yyyy'), to_date('03/31/2017', 'mm/dd/ yyyy')); 插入 zz_fatt (id, dstart, dend) 值 ('fat4', to_date('04/01/2017', 'mm/dd/yyyy'), to_date('04/30/2017', 'mm/dd/ yyyy')); 插入 zz_fatt (id, dstart, dend) 值 ('fat5', to_date('02/01/2017', 'mm/dd/yyyy'), to_date('03/31/2017', 'mm/dd/ yyyy')); 插入 zz_fatt (id, dstart, dend) 值 ('fat6', to_date('01/01/2017', 'mm/dd/yyyy'), to_date('02/28/2017', 'mm/dd/ yyyy')); 插入 zz_fatt (id, dstart, dend) 值 ('fat8', to_date('06/01/2017', 'mm/dd/yyyy'), to_date('06/15/2017', 'mm/dd/ yyyy'));

【问题讨论】:

    标签: sql database oracle


    【解决方案1】:

    您可以为记录分配组标识符。这个想法是找到不重叠的记录,并将它们用作组的开始。

    以下将组分配给每条记录:

      select t.*, sum(group_start) over (order by dstart) as grp
      from (select t.*,
                   (case when not exists (select 1
                                          from t t2
                                          where t2.dstart < t.dstart and t2.dend >= t.dstart
                                         )
                         then 1 else 0
                    end) group_start
            from t
           ) t
    

    如果您只想要某个记录的组,那么有几种方法,例如:

    with overlaps as (
          <query above>
         )
    select o.*
    from overlaps o
    where o.grp = (select o2.grp from overlaps o2 where o2.id = ???);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-19
      • 1970-01-01
      • 2020-07-28
      • 2011-05-27
      • 2021-11-14
      • 1970-01-01
      相关资源
      最近更新 更多