我有一张这样的表:
| 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'));
答案 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 = ???);