Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / PostgreSQL Новый топик    Ответить
 Объединение интервалов дат в случае пересечения или соприкосновения этих интервалов.  [new]
Vladislav1987
Member

Откуда:
Сообщений: 7
Доброй ночи.

Не могу режить задачу.
Нужно написать запрос, который по интервалам объединит эти интервалы в случае если они пересекаются или граничат.

Дано примерно так:

CREATE TABLE Quest(start_date date, end_date date);

INSERT INTO Quest VALUES('2020-01-01', '2020-01-15');
INSERT INTO Quest VALUES('2020-01-13', '2020-01-30');
INSERT INTO Quest VALUES('2020-02-01', '2020-02-05');
INSERT INTO Quest VALUES('2020-02-15', '2020-02-27');
INSERT INTO Quest VALUES('2020-02-16', '2020-02-19');
INSERT INTO Quest VALUES('2020-02-03', '2020-02-16');
INSERT INTO Quest VALUES('2020-03-01', '2020-05-04');
INSERT INTO Quest VALUES('2020-06-12', '2020-06-22');
INSERT INTO Quest VALUES('2020-04-17', '2020-06-19');

Результат должен быть:
2020-01-01, 2020-01-30
2020-02-01, 2020-02-27
2020-03-01, 2020-06-22

Думаю начало возможно такое:


WITH RECURSIVE sub(sub_line, start_date) AS
(
SELECT start_date, end_date
FROM Quest
ORDER BY start_date LIMIT 1

UNION ALL


--Далее адекватных идей нет.--


SELECT sub_line
FROM Quest q, sub s
WHERE q.end_date >= s.start_date

)
SELECT * FROM sub
30 мар 21, 01:16    [22301777]     Ответить | Цитировать Сообщить модератору
 Re: Объединение интервалов дат в случае пересечения или соприкосновения этих интервалов.  [new]
yob
Member

Откуда:
Сообщений: 39
Vladislav1987,
определите наименее гранулярную единицу - шаг (сек,мин,год)
смотрите насколько расходятся ближайшие точки в отсортированном списке, если больше чем единицу маркируйте как новый интервал(1,2,3), обыграйте краевые даты
для каждого промаркированного Min и Max, все
30 мар 21, 01:41    [22301781]     Ответить | Цитировать Сообщить модератору
 Re: Объединение интервалов дат в случае пересечения или соприкосновения этих интервалов.  [new]
yob
Member

Откуда:
Сообщений: 39
yob
Vladislav1987,
определите наименее гранулярную единицу - шаг (сек,мин,год)
смотрите насколько расходятся ближайшие точки в отсортированном списке, если больше чем единицу маркируйте как новый интервал(1,2,3), обыграйте краевые даты
для каждого промаркированного Min и Max, все

в вашем случае это просто день, с ним и работайте
30 мар 21, 02:11    [22301783]     Ответить | Цитировать Сообщить модератору
 Re: Объединение интервалов дат в случае пересечения или соприкосновения этих интервалов.  [new]
Vladislav1987
Member

Откуда:
Сообщений: 7
yob,

Добрый вечер.

Сочинил вот это. Дальше снова ступор.

SELECT
*
FROM
(
SELECT
SUB2.*,
CASE
WHEN end_date >= date_lagg
OR start_date < date_leadd
THEN 'per'
ELSE 'no'
END AS casee
FROM
(
SELECT
SUB.*,
start_date + lagg AS date_lagg,
end_date - leadd AS date_leadd
FROM
(SELECT
*,
end_date - start_date AS diff,
LAG((end_date - start_date), 1, 0) OVER(ORDER BY start_date) AS lagg,
LEAD((end_date - start_date), 1, 0) OVER(ORDER BY start_date) AS leadd
FROM
Quest) AS SUB) AS SUB2) AS SUB3
--WHERE casee = 'per'--

Сообщение было отредактировано: 30 мар 21, 22:11
30 мар 21, 22:18    [22302249]     Ответить | Цитировать Сообщить модератору
 Re: Объединение интервалов дат в случае пересечения или соприкосновения этих интервалов.  [new]
Щукина Анна
Member

Откуда:
Сообщений: 1512
Vladislav1987,

select min(start_date) as x_start_date, max(end_date) as x_end_date
  from (
         select  start_date, end_date, sum(sog) over(order by start_date,end_date) as grp_id
           from (
                  select start_date, end_date,
                         case 
                           when max(end_date) 
                               over(order by start_date, end_date 
                                        rows between unbounded preceding
                                                         and 1 preceding
                                   ) >= start_date
                           then 0 
                           else 1 
                         end as sog 
                    from quest t
                ) v0
       ) v1
 group by grp_id
 order by x_start_date;



Подсмотрено тут

Сообщение было отредактировано: 31 мар 21, 08:22
31 мар 21, 08:27    [22302321]     Ответить | Цитировать Сообщить модератору
 Re: Объединение интервалов дат в случае пересечения или соприкосновения этих интервалов.  [new]
Vladislav1987
Member

Откуда:
Сообщений: 7
Щукина Анна,

Огромное спасибо! Попытаюсь разобрать логику и шаги ответа.

yob,

Спасибо за участие. Сам за неимением опыта в SQL скорее всего запрос бы не написал.
31 мар 21, 21:01    [22302742]     Ответить | Цитировать Сообщить модератору
 Re: Объединение интервалов дат в случае пересечения или соприкосновения этих интервалов.  [new]
yob
Member

Откуда:
Сообщений: 39
Vladislav1987
Щукина Анна,

Огромное спасибо! Попытаюсь разобрать логику и шаги ответа.

yob,

Спасибо за участие. Сам за неимением опыта в SQL скорее всего запрос бы не написал.

Плохая практика писать множество вложенных запросов - дебажить тяжело.
31 мар 21, 23:03    [22302772]     Ответить | Цитировать Сообщить модератору
 Re: Объединение интервалов дат в случае пересечения или соприкосновения этих интервалов.  [new]
Maxim Boguk
Member

Откуда: Melbourne, Австралия
Сообщений: 4691
yob

Плохая практика писать множество вложенных запросов - дебажить тяжело.


А как по другому?
Вообще как раз вложенные позволяют нормально по отдельности их отладить проверяя каждую стадию.
Как раз Анна написала идеально почти даже с т.з. моего весьма придирчивого взгляда.
Все бы так писали.

PS: Анна а вы мои emails видели вообще?


--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
1 апр 21, 00:04    [22302779]     Ответить | Цитировать Сообщить модератору
Все форумы / PostgreSQL Ответить