Запрос SQL на четыре таблицы с MySQL - "пересечение"

У меня 4 стола

POST:
id

POST_TAG:
post_id
tag_id
value

TAG:
id

SEARCH:
tag_id
post_tag_value

Мне нужно запросить сообщения, которые имеют все теги и значения в виде строк в таблице поиска (а не только одно равное значение для тега):

РЕДАКТИРОВАТЬ: Извините за не предоставление текущего запроса и достаточно информации.

SELECT POST.id FROM POST,POST_TAG, SEARCH
WHERE
      POST.id = POST_TAG.post_id AND
      POST_TAG.tag_id= SEARCH.tag_id AND
      POST_TAG.value = SEARCH.value;

Это работает, если таблица SEARCH имеет одну строку. Проблема в том, когда его больше. Результатов должно быть меньше, но на самом деле их больше (если тест с 2 строками, правильные результаты - дублирующиеся строки; я ищу пересечение, а не объединение)

Добавлен sqlfiddle: http://sqlfiddle.com/

Результат запроса - "1", "1", "2". Это должно быть только "1", потому что у него есть оба "тега", в то время как у "2" есть только один.

2 ответа

Решение

Рабочий пример: http://sqlfiddle.com/

SELECT pt.post_id
FROM SEARCH s INNER JOIN post_tag pt ON pt.tag_id = s.tag_id AND pt.value = s.value
GROUP BY pt.post_id
HAVING COUNT(*) = (SELECT COUNT(*) FROM SEARCH)

Обратите внимание, что в вашей скрипке должен быть возвращен пост с идентификатором 0, так как он имеет (0,'yes') а также (1, 'yes') кортежи.

Согласно вашему sqlfiddle, ответ может быть следующим:

-- i want to select post that match to EVERY tag
-- the result of example data should be only '1'
SELECT POST.id as 'tag_id'
FROM POST,POST_TAG, SEARCH
WHERE
      POST.id = POST_TAG.post_id AND
      POST_TAG.tag_id= SEARCH.tag_id AND
      POST_TAG.value = SEARCH.value
GROUP BY POST.id
having COUNT(distinct POST_TAG.tag_id) = (select count(distinct tag_id) from POST_TAG);
Другие вопросы по тегам