如何在Oracle DB

时间:2017-05-16 15:48:26

标签: sql database oracle

我有一张这样的表:

| ID   | DSTART     | DEND
+------+------------+-----------
| fat1 | 01/01/2017 | 31/01/2017
| fat2 | 01/02/2017 | 28/02/2017
| fat3 | 01/03/2017 | 31/03/2017
| fat4 | 01/04/2017 | 30/04/2017
| fat5 | 01/02/2017 | 31/03/2017
| fat6 | 01/01/2017 | 28/02/2017
| fat7 | 01/03/2017 | 30/04/2017
| fat8 | 01/06/2017 | 30/06/2017
| fat9 | 28/04/2017 | 02/05/2017

给出记录我想找到所有重叠记录和重叠记录重叠的所有记录。

e.g。搜索fat7的重叠记录应该返回 fat5 (overlaps fat7) fat4 (overlaps fat7) fat3 (overlaps fat7) fat2 (*overlaps fat5) fat6 (*overlaps fat5) fat1 (**overlaps fat6)

创建数据集:

create table zz_fatt
( id      varchar2(100) primary key,
  dstart  date,
  dend    date);
insert into zz_fatt (id, dstart, dend) values ('fat7', to_date('03/01/2017', 'mm/dd/yyyy'), to_date('04/30/2017', 'mm/dd/yyyy'));
insert into zz_fatt (id, dstart, dend) values ('fat1', to_date('01/01/2017', 'mm/dd/yyyy'), to_date('01/31/2017', 'mm/dd/yyyy'));
insert into zz_fatt (id, dstart, dend) values ('fat2', to_date('02/01/2017', 'mm/dd/yyyy'), to_date('02/28/2017', 'mm/dd/yyyy'));
insert into zz_fatt (id, dstart, dend) values ('fat3', to_date('03/01/2017', 'mm/dd/yyyy'), to_date('03/31/2017', 'mm/dd/yyyy'));
insert into zz_fatt (id, dstart, dend) values ('fat4', to_date('04/01/2017', 'mm/dd/yyyy'), to_date('04/30/2017', 'mm/dd/yyyy'));
insert into zz_fatt (id, dstart, dend) values ('fat5', to_date('02/01/2017', 'mm/dd/yyyy'), to_date('03/31/2017', 'mm/dd/yyyy'));
insert into zz_fatt (id, dstart, dend) values ('fat6', to_date('01/01/2017', 'mm/dd/yyyy'), to_date('02/28/2017', 'mm/dd/yyyy'));
insert into zz_fatt (id, dstart, dend) values ('fat8', to_date('06/01/2017', 'mm/dd/yyyy'), to_date('06/15/2017', 'mm/dd/yyyy'));

1 个答案:

答案 0 :(得分:2)

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

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

  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 = ???);