SQL несколько диапазонов дат - PullRequest
0 голосов
/ 29 марта 2020

Мне нужно получить данные из таблицы, где дата находится в одном из нескольких диапазонов дат. Эти диапазоны дат находятся в другой таблице, и количество диапазонов дат варьируется.

Таблица диапазонов дат выглядит следующим образом:

+----------+------------+------------+
| variable | start_date |  end_date  |
+----------+------------+------------+
| A        | 2017-01-01 | 2017-02-05 |
| A        | 2018-07-04 | 2017-09-09 |
| A        | 2019-08-08 |            |
| B        | 2011-10-10 | 2012-02-05 |
+----------+------------+------------+

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

+----------+------------+--------------+
| variable |    date    | other_values |
+----------+------------+--------------+
| A        | 2017-01-04 |          123 |
| A        | 2016-07-04 |          123 |
| B        | 2020-01-01 |              |
| C        | 2018-02-07 |          123 |
+----------+------------+--------------+

Мне нужен запрос, который получает все строки из второй таблицы, где дата находится в одном из диапазонов дат первой таблицы. Если end_date имеет значение Null, date_range переходит от start_date к бесконечности.

Для каждой переменной у меня может быть различное количество строк в таблице диапазона дат.

Для этого примера мой вывод должно быть:

+----------+------------+--------------+
| variable |    date    | other_values |
+----------+------------+--------------+
| A        | 2017-01-04 |          123 |
| B        | 2020-01-01 |              |
+----------+------------+--------------+

Спасибо за помощь.

Ответы [ 2 ]

1 голос
/ 29 марта 2020

Вы можете использовать тип диапазона в Postgres:

select t2.*
from table_2 t2
where exists (select *
              from table_1 t1
              where t1.variable = t2.variable
                and t1.date <@ daterange(t1.start_date, t1.end_date, '[]'));

В диапазоне дат null рассматривается как открытый конец.

1 голос
/ 29 марта 2020

Один метод использует exists:

select t2.*
from t2
where exists (select 1
              from table1 t1
              where t1.variable = t2.variable and
                    t2.date >= t1.start_date and
                    (t2.date < t1.end_date or t1.end_date is null)
             );

У вас нет перекрывающихся диапазонов в первой таблице, поэтому вы также можете использовать join, не беспокоясь о дубликатах:

select t2.*
from t2 join
      t1
      on t1.variable = t2.variable and
         t2.date >= t1.start_date and
         (t2.date < t1.end_date or t1.end_date is null);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...