Разбить диапазоны дат в SQL на отдельные строки булевых дней - PullRequest
0 голосов
/ 12 сентября 2018

Предположим, у меня есть следующая таблица:

entry       exit
2017-05-12  2017-05-15
2017-05-19  2017-05-19
2017-05-21  2017-06-25
2017-06-29  2017-07-22

Используя SQL, я хочу разбить это на строки, где каждая строка представляет день и находится ли этот день внутри какого-либо из диапазонов.Например:

day        is_inside
2017-05-12 true
2017-05-13 true
2017-05-14 true
2017-05-15 true
2017-05-16 false
2017-05-17 false
2017-05-18 false
2017-05-19 true
2017-05-20 false
2017-05-21 true
...

Можно считать, что диапазоны не перекрываются.

Ответы [ 3 ]

0 голосов
/ 12 сентября 2018

Вы можете использовать generate_series для генерации дат между указанным начальным и конечным периодом. Затем таблицу можно left join отредактировать к этому, чтобы получить желаемый результат.

select t.dt,tbl.entry is null as is_inside
from generate_series('2018-05-12'::date,'2018-05-19','1 day') t(dt) --change the date range as needed
left join tbl on t.dt>=tbl.entry and t.dt<=tbl.exit
0 голосов
/ 12 сентября 2018

Вы можете использовать generate_series().Предполагая, что периоды не перекрываются:

select gs.dte, (t.entry is not null) as is_inside
from (select generate_series(min_entry, max_exit, interval '1 day) gs(dte)
      from (select min(entry) as min_entry, max(exit) as max_exit
            from t
           ) t
     ) gs left join
     t
     on gs.dte >= t.entry and gs.dte <= t.exit;

Два примечания:

  • В более поздних версиях Postgres я бы использовал боковое соединение, а не подзапрос для generate_series().
  • Если у вас есть перекрытия, используйте exists в select вместо left join.
0 голосов
/ 12 сентября 2018

Предполагается, что у вас есть таблица дат (счетная таблица для дат). Если нет, найдите таблицы дат и создайте их. В основном это таблица с одной строкой для каждой даты, которая позволяет легко выполнять запросы по диапазонам дат. У многих таблиц дат есть много других столбцов, но для этого вам просто нужен столбец даты. Вы можете создать временную таблицу дат для выполнения запроса, если вам нужно. Пример результат поиска .

Затем вы можете запросить в этой таблице интересующий вас диапазон дат и попытаться оставить внешнее соединение с таблицей диапазонов дат - если вы получили соединение, тогда оно истинно, иначе оно ложно. Примерно так (это может быть не точный синтаксис postgres, я ржавый на нем, но теория та же самая)

Select DT.Date, CASE WHEN DR.entry IS NULL THEN 'true' else 'false' end as is_inside
From DateTable DT 
    left outer join DateRange DR on DT.Date between DR.entry and DR.exit
Where DT.Date  ... (date range to report)

Если у вас, возможно, были перекрывающиеся диапазоны, все, что вам нужно было бы сделать, это различить результаты - у вас будет только один ложный или (один или несколько) истинных результатов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...