我有一个带有三列的表,polition_no,casenumber,created_date;可以为相同的唯一策略编号创建多个不同的案例号。除非最新创建的案例编号与在此之前创建的任何差距之间的差距少于三个月,否则我需要从表中删除所有数据。因此,例如,如果7月1日为策略编号创建了一个案例号,但是在此之前,也有在6月15日和5月1日相同的策略编号之前创建的案例号,我只想浏览该数据的数据7月1日创建的案例号,因为我只想计算一次唯一的策略编号。但是,当差距大于三个月以外,例如,当7月1日创建一个案件编号时,并且在4月30日创建之前创建了最后一个案例时,我想包括这些案例,并为2个案例包括2那个独特的政策号码。
我希望这一切都有意义!不知道从哪里开始!
首先,您应该意识到月份不是精确的时间单位。在这里,我使用了Oracle函数months_between
,但是您也可以提取日期并与30进行比较。Months_between
可以给出不直观但正确的结果。例如:
select months_between(date '2019-03-29', date '2019-02-28') from dual;
select months_between(date '2019-03-31', date '2019-02-28') from dual;
首先选择1.03
,第二个给出1
。奇怪但逻辑。这是因为月份不是精确的单位。
您已被警告:)现在解决方案。首先,我的示例数据,3个不同的策略编号,不同的情况:
create table policies(policy_no, casenumber, created_date) as (
select 1, 101, date '2007-01-01' from dual union all
select 1, 102, date '2007-02-01' from dual union all
select 1, 103, date '2007-06-01' from dual union all
select 1, 104, date '2007-09-15' from dual union all
select 1, 105, date '2007-11-01' from dual union all
select 1, 106, date '2007-12-01' from dual union all
select 2, 201, date '1992-08-30' from dual union all
select 3, 301, date '1995-07-12' from dual union all
select 3, 302, date '1995-08-30' from dual union all
select 3, 303, date '1997-02-25' from dual );
和我的查询:
with
t(pn, cn, cdt, rn) as (
select policy_no, casenumber, created_date,
row_number() over (partition by policy_no order by created_date desc)
from policies),
c(pn, cn, cdt, rn, diff, ldt, info) as (
select pn, cn, cdt, 1, 0, cdt, 'last' from t where rn = 1
union all
select t.pn, t.cn, t.cdt, t.rn, round(months_between(c.ldt, t.cdt), 2),
case when months_between(c.ldt, t.cdt) >= 3 then t.cdt else c.ldt end,
case when months_between(c.ldt, t.cdt) >= 3 then 'inlcuded' else 'excluded' end
from c join t on t.pn = c.pn and t.rn = c.rn + 1)
select * from c order by pn, rn
结果:
PN CN CDT RN DIFF LDT INFO
---------- ---------- ----------- ---------- ---------- ----------- --------
1 106 2007-12-01 1 0 2007-12-01 last
1 105 2007-11-01 2 1 2007-12-01 excluded
1 104 2007-09-15 3 2,55 2007-12-01 excluded
1 103 2007-06-01 4 6 2007-06-01 inlcuded
1 102 2007-02-01 5 4 2007-02-01 inlcuded
1 101 2007-01-01 6 1 2007-02-01 excluded
2 201 1992-08-30 1 0 1992-08-30 last
3 303 1997-02-25 1 0 1997-02-25 last
3 302 1995-08-30 2 17,84 1995-08-30 inlcuded
3 301 1995-07-12 3 1,58 1995-08-30 excluded
您仅对INFO last
或included
的行感兴趣。
它如何工作?子查询t
仅将编号添加到行中,这是针对每个策略脱核的,最新情况是首先。子查询c
是解决方案的主要部分。它是递归的。我们从行号1
开始,在下一步中,我们查找下一个行号,并检查其日期是否比记忆的三个月大。如果是我们保存它(在LDT列中(,如果否,则使用上一个。
这就是递归查询的工作方式。我希望我能正确理解。如果您只需要在相邻行之间检查,则功能lag
或lead
就足够了,但是在这里您需要递归。
希望这对任何语言错误有所帮助:(
以下查询将为您提供记录,以下情况下,政策案件相距超过3个月。90天。
SELECT A.POLICY_NO,
A.CASENUMBER,
A.CREATED_DATE,
B.CASENUMBER,
B.CREATED_DATE
FROM POLICY_CASES A, POLICY_CASES B
WHERE A.POLICY_NO = B.A.POLICY_NO
AND A.CASENUMBER <> B.CASENUMBER
AND B.CREATED_DATE > A.CREATED_DATE
AND (B.CREATED_DATE - A.CREATED_DATE) > 90
order by 1,3,5
需要更多数据,例如是否已经解决了提出的情况。包括其中或仅包括待定案件。或者您只需要最新和第二个。