Если вы хотите идентифицировать заметки, которые имеют связанные записи notes_tags с nt_tag_ids 10 и nt_tag_ids из 11, то внешнее объединение просто заставляет СУБД работать тяжелее, чем нужно.
Это кажется наиболее очевидным решением:
SELECT * FROM notes n
WHERE EXISTS (SELECT 1 FROM notes_tags nt
WHERE n.note_id=nt.nt_note_id
AND nt.nt_tag_id=10)
AND EXISTS (SELECT 1 FROM notes_tags nt2
WHERE n.note_id=nt2.nt_note_id
AND nt2.nt_tag_id=11);
Альтернативный подход:
SELECT n.*, COUNT(*)
FROM notes n,
notes_tags nt
WHERE n.note_id-nt.nt_note_id
AND nt.nt_tag_id IN (10,11)
GROUP BY .... /* need to add these */
HAVING COUNT(*)=2;
Обратите внимание, это предполагает, что они являются уникальным ограничением для nt_note_id и nt_tag_id в таблице notes_tags.оба приведенных выше вернут только данные в таблице заметок.Если вам нужно извлечь соответствующие строки из таблицы разложения MN:
SELECT *
FROM notes n,
notes_tags nt,
notes_tags nt2
WHERE n.note_id=nt.nt_note_id
AND n.note_id=nt2.note_id
AND nt.nt_note_id=nt2.nt_note_id /* can help the optimizer come up with a faster query */
AND nt.nt_tag_id=10
AND nt2.nt_tag_id=11
Возможно, вы захотите добавить псевдонимы в выходные столбцы, чтобы немного упростить анализ ответа.