Как сгруппировать дату начала и дату окончания нескольких записей в одном диапазоне с помощью sql

У меня есть запрос, который возвращает мне некоторые записи, как показано ниже:

ip; start_date; end_date
0.0.0.0; 09/10/2018 00: 00: 00; 10/10/2018 01:00:00
0.0.0.0; 10/10/2018 00: 00: 00; 11/10/2018 01:00:00
0.0.0.0; 10/10/2018 00: 00: 00; 11/10/2018 02:00:00
0.0.0.0; 10/10/2018 00: 00: 00; 11/10/2018 03:00:00
0.0.0.0; 10/10/2018 00: 00: 00; 11/10/2018 05:00:00
0.0.0.0; 10/12/2018 00: 00: 00; 10/10/2018 04:00:00

Как видите, у меня есть некоторые записи, которые, если мы сгруппируем по дате начала и окончания, окажутся в одном периоде;

как сгруппировать в запросе, чтобы получить записи следующим образом:

0.0.0.0; 09/10/2018 00: 00: 00; 11/10/2018 05:00:00
0.0.0.0; 10/12/2018 00: 00: 00; 10/10/2018 04:00:00

Как видите, первые 5 строк содержатся в одном диапазоне, а последняя строка — нет.


person user3308496    schedule 11.09.2019    source источник
comment
Последний диапазон, по-видимому, имеет end_date перед start_date   -  person Nick    schedule 12.09.2019
comment
Какую СУБД вы используете?   -  person GMB    schedule 12.09.2019
comment
Помимо наблюдения Ника... при каком условии вы хотите, чтобы два интервала находились в одной группе? Что существует путь перекрывающихся интервалов между ними? Ну, это будет пахнуть рекурсивным-с-оператором или чем-то в этом роде, я думаю   -  person Islingre    schedule 12.09.2019


Ответы (1)


Вы можете использовать кумулятивный max(), чтобы увидеть, где есть перекрытия. Там, где нет перекрытия, начинается группа. Совокупная сумма начала определяет каждый «остров», а последний шаг — агрегация:

select ip, grp,
       min(start_date), max(end_date)
from (select t.*,
             sum(case when prev_max_end_date >= start_date
                      then 0 else 1
                 end) over (partition by ip order by start_date) as grp
      from (select t.*,
                   max(end_date) over (partition by ip 
                                       order by start_date
                                       rows between unbounded preceding and 1 preceding
                                      ) as prev_max_end_date
            from t
           ) t
      ) t
group by ip, grp;
person Gordon Linoff    schedule 12.09.2019