Sql 提取满足某些时间间隔条件的时间点

Sql 提取满足某些时间间隔条件的时间点,sql,oracle,time,aggregation,Sql,Oracle,Time,Aggregation,我四处寻找,没有找到解决办法。有用的读物 这是我的数据:规则是 对于每个国家/地区,按时间间隔等于或大于5个月的顺序选择日期ID 我的工作环境是ORACLE SQL 非常感谢 Country Date_ID ---------------------- USA 199003 USA 200004 USA 200005 USA 200009 USA 200010 UK

我四处寻找,没有找到解决办法。有用的读物

这是我的数据:规则是

对于每个国家/地区,按时间间隔等于或大于5个月的顺序选择日期ID

我的工作环境是ORACLE SQL

非常感谢

Country       Date_ID
----------------------
USA           199003
USA           200004
USA           200005
USA           200009
USA           200010
UK            199307
UK            199308
UK            199408
因此,输出应该是

 Country    Date_ID
 --------------------
 USA        199003
 USA        200004
 USA        200009
 UK         199307
 UK         199408

这里有一种方法可以解决这个问题,至少可以追溯到Oracle 10.2。它使用分析函数和分层查询

WITH子句仅用于动态构建示例数据。您不需要它-删除它,并在查询中使用实际的表名和列名。在WITH子句中,我在CTE名称后声明了列,CTE名称仅在Oracle 11.2及更高版本中有效,但WITH子句不是解决方案的一部分,因此我不担心这一点

with
  sample_data (country, date_id) as (
    select 'USA', 199003 from dual union all
    select 'USA', 200004 from dual union all
    select 'USA', 200005 from dual union all
    select 'USA', 200009 from dual union all
    select 'USA', 200010 from dual union all
    select 'UK' , 199307 from dual union all
    select 'UK' , 199308 from dual union all
    select 'UK' , 199408 from dual
  )
select country, date_id
from   (
         select country, date_id,
                row_number() over (partition by country order by dt) as rn,
                count(*) over (partition by country order by dt
                  range between current row 
                            and interval '4' month following) as ct
         from   (
                  select country, date_id, 
                         to_date(to_char(date_id, 'fm999999'), 'yyyymm') as dt
                  from   sample_data
                )
       )
start with rn = 1
connect by country = prior country and rn = prior rn + prior ct
;

COUNTRY    DATE_ID
------- ----------
UK          199307
UK          199408
USA         199003
USA         200004
USA         200009
作为比较,这里有一个match_Recognite解决方案,它需要Oracle 12.1或更高版本:

select country, date_id
from   (
         select country, date_id, 
                to_date(to_char(date_id, 'fm999999'), 'yyyymm') dt
         from   sample_data
       )
match_recognize(
  partition by country
  order by     date_id
  all rows per match
  pattern      (a {- b* -})
  define b as  dt < add_months(a.dt, 5)
);

嗨,贾尔赫,谢谢你的评论。我不确定我的问题是否令人困惑。实际上,我是在按顺序选择日期。以美国为例,1990/03和2000/04的时间间隔大于5个月。但是,2000/05到2000/04不在5个月内,因此不选择2000/05。您的Oracle版本是什么?在Oracle 12.1及更高版本中,使用match_Recognite,该问题很容易解决;在旧版本中更难。另外,日期ID的数据类型是什么?它们是字符串还是正确的数据类型,即日期?@mathguy,你说得对…@mathguy我的oracle是11.2日期\u ID是数字6。如果您知道这个版本中的一些解决方案,那就太好了。如果没有,我非常感谢Oracle 12.1或Mysql.etc中的任何建议/文档。这正是我要寻找的,也是非常聪明的答案。我测试它,它的工作!我需要一些时间来消化它,并会让你不断更新。谢谢大家!@user1503-在研究解决方案时,请随时提出后续问题。嗨,Mathguy,非常感谢您的回答,我学习了很多有用的函数工具。然而,我最近遇到了一个问题,这个问题似乎无法通过匹配识别来解决。滑动窗似乎是一个不错的选择。我贴出了这个问题,我在这里的行为似乎不适合再问你一个问题。如果是这样,我将删除此消息。一如既往地谢谢你。