我有一个包含三列的表,policy_no,casenumber,created_date;可以为同一唯一策略编号创建多个不同的案例编号。我需要遍历表中的所有数据,除非最新创建的案例编号与之前创建的案例编号之间的间隔不足三个月。因此,例如,在7月1日为保单号创建了案例号,但是在6月15日和5月1日为同一保单号创建了案例号之前,我只想获取案例编号是在7月1日创建的,因为我只想对该唯一的策略编号进行一次计数。但是,如果差距大于三个月,例如,当一个案例号是在7月1日创建的,而最后一个案例是在4月30日创建的,那么我想将这两个案例都包括在内,并且有2个该唯一的政策编号。
我希望所有这些都有意义!不知道从哪里开始!
答案 0 :(得分:1)
首先,您应该意识到month不是精确的时间单位。在这里,我使用了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
。奇怪但合乎逻辑。这是因为月份不是精确的单位。
警告您:)现在解决。首先是我的样本数据,三个不同案例的不同政策编号:
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
您仅对信息为last
或included
的行感兴趣。
它如何工作?子查询t
仅在行中添加编号,对于每个分离的策略,最新的情况在第一位。子查询c
是解决方案的主要部分。
它是递归的。我们从行号1
开始,然后在每个下一步中寻找下一个行号,并检查其日期是否比记住的日期早三个月。
如果是,则将其保存(在ldt列中),否则,将使用前一个。
这是递归查询的工作方式。我希望我能正确理解。如果只需要在相邻行之间进行检查,则函数lag
或lead
就足够了,但是这里需要递归。
希望这对您有所帮助,对于任何语言错误:)
答案 1 :(得分:0)
以下查询将为您记录相距三个月以上的政策案例。 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
还需要更多数据,例如,已经解决了引发的问题。包括或仅包括未决案件。或者您只想要最新的和倒数第二个等等。