Sql 为唯一保单编号创建案例编号之间至少间隔三个月

Sql 为唯一保单编号创建案例编号之间至少间隔三个月,sql,oracle,Sql,Oracle,我有一个表,有三列,政策号,案例号,创建日期;可以为同一唯一保单编号创建多个不同的案例编号。我需要从表中提取所有数据,除非最新创建的案例编号与在此之前创建的案例编号之间的差距小于三个月。例如,如果在7月1日为保单编号创建了一个案例编号,但在6月15日和5月1日为同一保单编号创建了案例编号,那么我只想查看7月1日创建的案例编号的数据,因为我只想计算唯一的保单编号一次。但是,当差距大于三个月时,例如,在7月1日创建了一个案例编号,而在这之前创建的最后一个案例编号是在4月30日创建的,那么我想将这两个

我有一个表,有三列,政策号,案例号,创建日期;可以为同一唯一保单编号创建多个不同的案例编号。我需要从表中提取所有数据,除非最新创建的案例编号与在此之前创建的案例编号之间的差距小于三个月。例如,如果在7月1日为保单编号创建了一个案例编号,但在6月15日和5月1日为同一保单编号创建了案例编号,那么我只想查看7月1日创建的案例编号的数据,因为我只想计算唯一的保单编号一次。但是,当差距大于三个月时,例如,在7月1日创建了一个案例编号,而在这之前创建的最后一个案例编号是在4月30日创建的,那么我想将这两个案例都包括在内,并将该唯一保单编号的计数设为2


我希望这一切都有意义!不知道从哪里开始这一个

以下查询将为相隔3个月以上的保单案例提供u记录。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
选择一个策略\u编号,
A.案件编号,
创建日期,
B.案件编号,
创建日期
从政策案例A到政策案例B
其中A.POLICY\u NO=B.A.POLICY\u NO
A.案件编号B.案件编号
和B.创建日期>A.创建日期
和(B.创建日期-A.创建日期)>90
以1,3,5的顺序

需要更多的数据,比如所提出的问题是否已经解决。包括或仅包括未决案件。或者您只需要最新和倒数第二等。首先,您应该知道这不是一个精确的时间单位。在这里,我使用了Oracle函数
months\u,介于
之间,但您也可以减去日期并与30进行比较<代码>介于
之间的月份可能会给出不直观但正确的结果。例如:

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
您只对包含信息
last
的行感兴趣

它是如何工作的?子查询
t
只对行添加编号,它是针对每个单独的策略,最新的案例是第一个。子查询
c
是解决方案的主要部分。 它是递归的。我们从行号
1
开始,在接下来的每一步中,我们寻找下一个行号,并检查其日期是否早于记忆的三个月。 如果是,我们保存它(在ldt列中),如果不是,则使用前一个

这就是递归查询的工作原理。我希望我理解正确。如果只需要在相邻行之间进行检查,那么函数
lag
lead
就足够了,但这里需要递归


希望这对您有所帮助,并为您的语言错误感到抱歉:)

但是如果日期是7月1日、5月1日和3月1日呢?间隔为2个月,但最后一个和第一个之间的间隔为4个月。答案取决于你想要两行还是一行。嗨,只有在3月1日提出的案例才应该包括在内。基本上,只要在上一次查询的90天内提出案例,就应该在查询中替换该案例。因此,仅包括最近的病例,以及在随后90天内没有提出进一步病例的病例。如果在2019年3月1日之后,在2019年5月30日之前没有提出进一步的案件,那么在3月1日提出的案件将被“存入银行”,并且现在总是包括在查询中,在2019年5月30日提出的案件也将被包括在内(除非在90天内提出另一个案件,这将被包括在内)。嗨,基本上每过三个月,循环将再次开始。因此,如果在2019年1月1日、2019年1月15日、2019年2月24日、2019年5月25日、2019年5月31日、2019年6月30日和2019年9月28日针对保单提出了案例,则应包含在查询中的案例是在2019年2月24日、2019年6月30日和2019年9月28日提出的案例。因此,始终包括最新的案例,以及在未来90天内没有提出额外案例的任何案例。如果随后在2019年9月30日提出了另一个案件,这将取代2019年9月28日提出的案件,因为该案件不应再包括在内。希望这一切都有意义!非常感谢你,我将在今晚完成工作,充分理解你所做的一切。在我看来,这是一项很棒的工作。谢谢嗨,太近了。这是它能碰到的地方。我有一个在以下日期记录案例的政策示例;19年4月16日(上次)19年1月22日(exc)18年5月14日(exc)18年3月14日(exc)29年12月17日(inc)05年9月17日(inc)22年8月17日(exc)19年7月17日(exc)04年7月17日(exc)12月17日(exc)17日(exc)13月16日(inc)17日的案件被包括在内,尽管另一个案件于2017年7月4日被提出。代码还能更好吗?如果没有,我会接受你写的,非常感谢。但是2017年7月4日被排除在外(因为之前的银行是2017年9月5日)。所以5月17日12日也包括在内。请看这封信和你提到的确切日期。它在每一行中显示最后一个银行日期和月差,这就是为什么包含或排除检查日期的原因。它几乎运行良好,但它需要计算案例创建日期和之后创建的下一个案例之间的差距。因此,2017年5月12日创建的案例与2017年7月4日创建的下一个案例之间的差异为1.74,因此应排除2017年5月12日的案例,但2017年9月5日创建的案例与2017年12月29日创建的下一个案例之间的差异为3.4,因此2017年9月5日的案例应存入银行并纳入。希望一切都很清楚,很抱歉这样的痛苦!