比较特定位置的两个日期之间的日期

Compare dates between two dates at specific positions

给定 table 中的以下示例记录:MY_DATES,使用 Oracle SQL and/or PL/SQL,我需要一直拿这个table中的第一个DATE_REGISTERED,即26/10/2019,然后前进到第三个DATE_REGISTEREDrecord/value,即2/02/ 2020 并检查它们之间的差异是否大于 13 周,即

select to_date('2/02/2020','dd/mm/yyyy') - to_date('26/10/2019','dd/mm/yyyy') a from dual

Table Name: MY_DATES

NM  DATE_REGISTERED
--- ---------------
A1  26/10/2019
A1  2/11/2019
A1  2/02/2020
A1  9/02/2020
A1  16/02/2020
A1  23/02/2020
A1  1/03/2020
A1  8/03/2020

此练习的最终结果是 return 满足此条件的不同 NM 值数据。

这似乎很奇怪。我在想 lead()lag)。如果你想要满足条件的nm值:

select md.*
from (select md.*,
             lead(date_registered, 2) over (partition by nm order by date_registered) as next_dr_2,
             lag(date_registered) over (partition by nm order by date_registered) as prev_dr
      from my_dates md
     ) md
where prev_dr is null and
      next_dr_2 > date_registered + interval '91' day;

这是一个使用 MATCH_RECOGNIZE 子句的高效解决方案,在 Oracle 版本 12.1 中引入。

WITH 子句模拟输入数据(它不是解决方案的一部分 - 删除它并在主查询中引用您的实际 table 和列名)。

解决方案按 NM 分区并按 DT 排序,然后它查找连续的三行,其中第三个日期比第一个日期晚了 13 周以上。一旦发现这样的事件,它就会用分区中所有剩余的行填充 "match pattern",基本上将它们丢弃 - 因为我们只关心单个匹配项。

注意我添加的两个 NM。 BB 确实有相隔超过 13 周的日期,但不在连续三个日期内。 CC 有两个连续的日期已经相隔超过 13 周; CC 不在输出中,因为没有三个不同的日期开始。 (注意 - 这就是我阅读要求的方式;如果需要的是 "consecutive dates more than 13 weeks apart should also count",那可以很容易地解决 - 但这不是张贴者问题中的措辞。)

with
  my_dates (nm, date_registered) as (
    select 'A1', to_date('26/10/2019', 'dd/mm/yyyy') from dual union all
    select 'A1', to_date( '2/11/2019', 'dd/mm/yyyy') from dual union all
    select 'A1', to_date( '2/02/2020', 'dd/mm/yyyy') from dual union all
    select 'A1', to_date( '9/02/2020', 'dd/mm/yyyy') from dual union all
    select 'A1', to_date('16/02/2020', 'dd/mm/yyyy') from dual union all
    select 'A1', to_date('23/02/2020', 'dd/mm/yyyy') from dual union all
    select 'A1', to_date( '1/03/2020', 'dd/mm/yyyy') from dual union all
    select 'A1', to_date( '8/03/2020', 'dd/mm/yyyy') from dual union all
    select 'BB', to_date( '2/03/2019', 'dd/mm/yyyy') from dual union all
    select 'BB', to_date('14/03/2019', 'dd/mm/yyyy') from dual union all
    select 'BB', to_date('18/03/2019', 'dd/mm/yyyy') from dual union all
    select 'BB', to_date('10/06/2019', 'dd/mm/yyyy') from dual union all
    select 'BB', to_date( '3/04/2019', 'dd/mm/yyyy') from dual union all
    select 'CC', to_date('15/08 2019', 'dd/mm/yyyy') from dual union all
    select 'CC', to_date('15/02/2020', 'dd/mm/yyyy') from dual
  )
-- end of sample data (for testing only); query begins below this comment
select nm
from   my_dates
match_recognize(
  partition by nm
  order     by date_registered
  pattern   ( a b c x* )
  define    c as date_registered > a.date_registered + 91
);



NM
----
A1

** 编辑 **

重新阅读问题,似乎只应考虑 前三个日期 (而不是 任何三个连续的 日期) .

这样问题就简单多了。并且解决方案可以轻松修改 - 唯一需要更改的是 pattern 子句,它应该变成:

pattern ( ^ a b c )

这会将对三行的搜索定位在分区的开头。其他行未检查。