Запрос 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);