WITH TAB AS (SELECT '0002' BUSINESSNO, 2 BUSINESSTYPE, DATE '2012-1-1' STARTDATE, DATE '2018-5-25' ENDDATE, 79 FILESERIALNO FROM DUAL UNION ALL SELECT '00001', 3, DATE '2012-1-1', DATE '2018-9-19', 79 FROM DUAL UNION ALL SELECT '75157623-8', 1, DATE '2012-5-1', DATE '2013-4-29', 79 FROM DUAL UNION ALL SELECT '75157623-8', 1, DATE '2013-5-1', DATE '2014-5-1', 79 FROM DUAL UNION ALL SELECT '75157623-8', 1, DATE '2014-5-2', DATE '2018-4-29', 79 FROM DUAL)
--当一个日期范围可以匹配3条记录,即3个证件都在有效期内,则合同可以签署 --这个例子中count为2,不符合条件 SELECT COUNT(1) FROM ( --找出每个证件类型,以及对应的连续区间 SELECT BUSINESSTYPE, MIN(STARTDATE) STARTDATE, MAX(ENDDATE) ENDDATE FROM (SELECT BUSINESSNO, BUSINESSTYPE, STARTDATE, ENDDATE, ROW_NUMBER() OVER(PARTITION BY BUSINESSTYPE ORDER BY STARTDATE) RN, LAG(ENDDATE) OVER(PARTITION BY BUSINESSTYPE ORDER BY STARTDATE) LAG_ENDDATE FROM TAB WHERE FILESERIALNO = 79) START WITH LAG_ENDDATE IS NULL OR LAG_ENDDATE < STARTDATE - 1 CONNECT BY RN = PRIOR RN + 1 AND LAG_ENDDATE >= STARTDATE - 1 AND BUSINESSTYPE = PRIOR BUSINESSTYPE GROUP BY BUSINESSTYPE, RN - LEVEL) WHERE DATE '2013-4-30' >= STARTDATE AND DATE '2016-5-1' <= ENDDATE
select count(distinct bussinesstype) cnt from (select level, connect_by_isleaf leaf, connect_by_root(startdate) root, a.* from 数据表 start with startdate <= date '2014-4-30' connect by startdate = prior enddate + 1 and bussinesstype = prior bussinesstype) where leaf = 1 and enddate >= date '2016-5-26'
select count(distinct bussinesstype) cnt from (select level, connect_by_isleaf leaf, connect_by_root(startdate) root, a.* from 数据表 a start with startdate <= date '2014-4-30' connect by startdate = prior enddate + 1 and bussinesstype = prior bussinesstype) where leaf = 1 and enddate >= date '2016-5-26'
with TT as (select '3060' sn,'2' bt,to_date('20120101','yyyymmdd') sd,to_date('20180525','yyyymmdd') ed from dual union all select '3061' sn,'3' bt,to_date('20120101','yyyymmdd') sd,to_date('20180919','yyyymmdd') ed from dual union all select '3177' sn,'1' bt,to_date('20120501','yyyymmdd') sd,to_date('20130429','yyyymmdd') ed from dual union all select '3176' sn,'1' bt,to_date('20130501','yyyymmdd') sd,to_date('20140501','yyyymmdd') ed from dual union all select '3063' sn,'1' bt,to_date('20140502','yyyymmdd') sd,to_date('20180526','yyyymmdd') ed from dual), T1 as(select sn,bt,greatest(sd - to_date('20130430','yyyymmdd'),0) sa,greatest(sd - to_date('20160501','yyyymmdd'),0) sb, greatest(ed - to_date('20130430','yyyymmdd'),0) ea,greatest(ed - to_date('20160501','yyyymmdd'),0) eb from TT) select T1.bt,to_date('20160501','yyyymmdd') - to_date('20130430','yyyymmdd') ab,sum(ea-sa-eb)+(select count(*)-1 from T1 s where s.bt=t1.bt and ea-sa-eb>0) cc from T1 group by bt order by bt
注:ea-sa-eb即是该记录落在各有效期的天数,而 (select count(*)-1 from T1 s where s.bt=t1.bt and ea-sa-eb>0) 则是分段(有效段)补偿数