Эффективный способ поиска недостающих строк в нескольких соединениях

Учитывая следующую схему, где участники могут делиться правами на должности:

member: id, name, ...
post_owner: member_id, post_id
post: id, created, ...

Самый эффективный запрос для поиска пользователей, которые не занимали должность за последние 90 дней.

Я думал об этом, но кажется неэффективным:

select *
from member
where member_id not in (
 select member_id
 from post p
 join post_owner po on po.post_id = p.id
 where created > subdate(now(), 90))

Предположим, что есть индекс на post(created) и все внешние ключи.

3 ответа

SELECT m.id, m.name 
FROM member m 
LEFT JOIN post_owner po ON m.id = po.member_id 
LEFT JOIN post p ON po.post_id = p.id AND p.created >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
WHERE p.id IS NULL

Подсказка: сравните p.created с константой, чтобы использовать индексы.


как насчет этого?

SELECT m.id, m.name 
From post p
INNER JOIN post_owner po ON po.post_id = p.id AND
RIGHT JOIN member m ON m.id = po.member_id
where DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY) <= created


Попробуй это:

SELECT m.id, m.name 
FROM member m 
LEFT JOIN post_owner po ON m.id = po.member_id 
LEFT JOIN post p ON po.post_id = p.id AND DATEDIFF(CURRENT_DATE(), p.created) <= 90
WHERE p.id IS NULL

licensed under cc by-sa 3.0 with attribution.