Как отфильтровать запрос по трем таблицам за определенный промежуток времени?

Дано: PostgreSQL

Таблица link с колонкой id.
Таблица campaigns c колонкой link_id (ссылается на таблицу 1).
Таблица click с колонкой link_id (ссылается на таблицу 1) и колонкой created_at (дата).

Необходимо проверить что отсутствуют такие записи таблицы link:

  • у которых нет связанных записей в таблице campaigns
  • у которых нет связанных записей в таблице click за последние три месяца
SELECT link.id link_id,
       campaigns.link_id campaigns_link_id,
       click.link_id click_link_id
FROM link
FULL JOIN campaigns
ON link.id = campaigns.link_id
JOIN click
ONlink.id = click.link_id

WHERE campaigns.link_id is null
AND
click.created_at >= '2023-08-16 09:16:41'
;

Этот запрос выводит записи из таблицы link у которых ЕСТЬ связанные записи с таблицей click за последние три месяца. Я никак не могу придумать что нужно изменить, чтобы получить линки у которых НЕТ связанных записей с таблицей click за последние три месяца.


Ответы (1 шт):

Автор решения: pegoopik

Почитайте про LEFT JOIN, и особенно о том, чем отличаются условия в WHERE от условий в LEFT JOIN. Если кратко, WHERE действует на всё предложение FROM, а условие в JOIN только на условие присоединения конкретной таблицы. Тогда как-то так:

SELECT link.id link_id,
       campaigns.link_id campaigns_link_id,
       click.link_id click_link_id
FROM link
  LEFT JOIN campaigns ON link.id = campaigns.link_id
  LEFT JOIN click ON link.id = click.link_id
    AND click.created_at >= '2023-08-16 09:16:41'
WHERE 
  campaigns.link_id is null AND click.link_id is null

Но, если в таблице link записей много, возможно выгодней будет использовать NOT EXISTS или EXCEPT, надо смотреть на конкретный данных.

→ Ссылка