我们可以看到,对于同一个客户和合同组合,我们有多个周期,但是一个周期的结束日期与另一个周期的开始日期之间存在差距。
我想在我的表中找到所有存在多个周期缺口的客户和合同组合。不一定要结束最新周期。它的默认结束日期可以为01/01/3000,表示该周期仍处于活动状态。
有人可以帮我查询吗?
Customer_ID Contract_Id Start_Date End_Date
1 21 01/01/2018 02/01/2018
1 21 02/06/2018 03/01/2018
答案 0 :(得分:2)
我认为您可以使用LEAD分析功能来获取下一个周期的开始日期,然后将其与期间的结束日期进行比较:
create table contracts (
Customer_ID number,
Contract_Id number,
Start_Date date,
End_Date date
);
-- with gap
insert into contracts values (1, 21, to_date('01/01/2018','MM/DD/YYYY') , to_date('02/01/2018','MM/DD/YYYY'));
insert into contracts values (1, 21, to_date('02/06/2018','MM/DD/YYYY'), to_date('03/01/2018','MM/DD/YYYY'));
-- no gap (next start_date = end_date+1)
insert into contracts values (2, 21, to_date('01/01/2018','MM/DD/YYYY') , to_date('02/01/2018','MM/DD/YYYY'));
insert into contracts values (2, 21, to_date('02/02/2018','MM/DD/YYYY'), to_date('03/01/2018','MM/DD/YYYY'));
-- with gap. no end date
insert into contracts values (3, 21, to_date('01/01/2018','MM/DD/YYYY') , to_date('02/01/2018','MM/DD/YYYY'));
insert into contracts values (3, 21, to_date('02/06/2018','MM/DD/YYYY'), null);
-- no gap, no end date
insert into contracts values (4, 21, to_date('01/01/2018','MM/DD/YYYY') , to_date('02/01/2018','MM/DD/YYYY'));
insert into contracts values (4, 21, to_date('02/02/2018','MM/DD/YYYY'), null);
-- one period
insert into contracts values (5, 21, to_date('01/01/2018','MM/DD/YYYY') , to_date('02/01/2018','MM/DD/YYYY'));
-- one period, no end date
insert into contracts values (6, 21, to_date('01/01/2018','MM/DD/YYYY') , null);
commit;
select customer_id, contract_id, start_date, end_date, next_start_date, (next_start_date-end_date) as gap
from (
select customer_id, contract_id, start_date, end_date,
lead(start_date, 1, end_date+1) over (partition by customer_id, contract_id order by start_date) next_start_date
from contracts
)
where next_start_date != end_date + 1;
CUSTOMER_ID CONTRACT_ID START_DAT END_DATE NEXT_STAR GAP
----------- ----------- --------- --------- --------- ----------
1 21 01-JAN-18 01-FEB-18 06-FEB-18 5
3 21 01-JAN-18 01-FEB-18 06-FEB-18 5
答案 1 :(得分:1)
您也可以通过使用自联接来实现此目的。
我尝试使用自连接解决以下问题:
-- GAP IN PERIOD
SELECT
C1.CUSTOMER_ID,
C1.CONTRACT_ID,
C1.START_DATE AS START_DATE,
C1.END_DATE AS END_DATE,
C2.START_DATE - C1.END_DATE AS GAP,
C2.START_DATE AS NEXT_START_DATE
FROM
CONTRACTS C1
JOIN CONTRACTS C2 ON ( C1.CUSTOMER_ID = C2.CUSTOMER_ID
AND C1.CONTRACT_ID = C2.CONTRACT_ID
AND C2.START_DATE > C1.START_DATE
AND C2.START_DATE - C1.END_DATE <> 1
AND C2.START_DATE - C1.END_DATE > 0) -- ADDED THIS CONDITION
注意:在查找重叠的周期时,我在当前代码中发现了一个问题,并且已将其纠正-最后一个条件
输出:
注意:我已经使用了上一个答案中的相同数据。
干杯!
-
查询以查找重叠周期:
-- OVERLAPPING IN PERIOD
SELECT
C1.CUSTOMER_ID,
C1.CONTRACT_ID,
C1.START_DATE AS START_DATE,
C1.END_DATE AS END_DATE,
C2.START_DATE - C1.END_DATE AS GAP,
C2.START_DATE AS NEXT_START_DATE
FROM
CONTRACTS C1
JOIN CONTRACTS C2 ON ( C1.CUSTOMER_ID = C2.CUSTOMER_ID
AND C1.CONTRACT_ID = C2.CONTRACT_ID
AND C2.START_DATE > C1.START_DATE
AND C2.START_DATE - C1.END_DATE <> 1
AND C2.START_DATE - C1.END_DATE < 0)
输出:
干杯!