SQL: выбор между датами

#sql #database

#sql #База данных

Вопрос:

У меня есть две таблицы, которые выглядят как:

 table A:
ID, target_date, target_ID

table B:
ID, target_ID, begin_date, end_date
  

В таблице B может быть несколько записей для одного и того же target_ID, но разных диапазонов дат. Меня интересует SQL-запрос, который может возвращать target_dates, которые не входят в диапазоны begin_date и end_date для данного target_ID.

Комментарии:

1. Можете ли вы предоставить примеры того, что вы уже пробовали?

2. Возможно, это не так важно, но вам следует добавить тег для используемой вами СУБД (Postgres, Oracle, …)

Ответ №1:

В этом есть хитрость. Найдите совпадающие, используя a left join , а затем выберите те, которые не совпадают:

 select a.*
from tablea a left join
     tableb b
     on a.target_id = b.target_id and
        a.target_date between b.begin_date and b.end_date
where b.target_id is null;
  

Вы можете выразить это несколькими различными способами. Например, not exists также может показаться естественным:

 select a.*
from tablea a
where not exists (select 1
                  from tableb b
                  where a.target_id = b.target_id and
                        a.target_date between b.begin_date and b.end_date
                 );
  

Примечание: я использую between для этих сравнений удобное сокращение (в соответствии с языком, который вы используете в вопросе). Часто с датами предпочтительнее явное использование < , <= , > , или >= .

Ответ №2:

 SELECT A.target_date 
FROM A LEFT OUTER JOIN B 
     ON (A.target_ID=B.target_ID 
     AND A.target_date>=B.begin_date 
     AND A.target_date<=B.end_date) 
WHERE B.begin_date IS NULL
  

Ответ №3:

Может быть:

 SELECT target_date FROM A 
   INNER JOIN B 
   ON A.target_ID = B.target_ID
WHERE target_date NOT BETWEEN begin_date AND end_date