提取满足某些时间间隔标准的时间点
Extract time points meeting some time interval criteria
我四处寻找,没有找到解决办法。 (有用的读物SQL to find time elapsed from multiple overlapping intervals)
这是我的数据:规则是
"For each country, select the Date_ID in sequence with time interval equal or greater than 5 months"
我的工作环境是ORACLESQL。
非常感谢。
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 子句只是用来动态构建示例数据。您不需要它 - 删除它,并在查询中使用您实际的 table 和列名。 (在 WITH 子句中,我在 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_recognize
解决方案,需要 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)
);
我四处寻找,没有找到解决办法。 (有用的读物SQL to find time elapsed from multiple overlapping intervals)
这是我的数据:规则是
"For each country, select the Date_ID in sequence with time interval equal or greater than 5 months"
我的工作环境是ORACLESQL。
非常感谢。
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 子句只是用来动态构建示例数据。您不需要它 - 删除它,并在查询中使用您实际的 table 和列名。 (在 WITH 子句中,我在 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_recognize
解决方案,需要 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)
);