Извлечение временных точек, соответствующих некоторым временным интервалам - PullRequest
0 голосов
/ 27 ноября 2018

Я искал вокруг и не нашел решения.(Полезное чтение SQL, чтобы найти истекшее время из нескольких перекрывающихся интервалов )

Вот мои данные: правила

"Для каждой страны выберите Date_ID в последовательностис интервалом времени, равным или превышающим 5 месяцев "

Моя рабочая среда 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

1 Ответ

0 голосов
/ 27 ноября 2018

Вот один из способов решения этой проблемы, который будет работать, по крайней мере, еще до Oracle 10.2.Он использует аналитические функции и иерархический запрос.

Предложение WITH предназначено только для создания примеров данных на лету.Вам это не нужно - удалите его и используйте ваши фактические имена таблиц и столбцов в запросе.(В предложении 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)
);
...