Фильтрация из таблицы соединений - PullRequest
1 голос
/ 15 марта 2009

У меня возникли проблемы с хитрым SQL-запросом.

В моей базе данных MySQL есть таблицы разделов, теги и tags_topics для присоединения к ним. Я хочу получить темы с одинаковыми указанными тегами. Например, скажем, у меня есть 3 тега с идентификаторами 1, 2 и 3, я хочу получить все темы, с которыми связаны теги 1, 2 и 3. Темы могут иметь другие теги, но должны иметь все указанные теги.

Помоги мне подумать, плз xD

РЕДАКТИРОВАТЬ: нашел решение с использованием GROUP BY в этом вопросе: Выборка только строк, которые соответствуют всем записям в объединенной таблице (SQL) Если у кого-нибудь есть более элегантное решение, пожалуйста, напишите:)

Ответы [ 2 ]

4 голосов
/ 15 марта 2009

JOIN решение:

SELECT t.*
FROM topics t
 JOIN tags_topics t1 ON (t.id = t1.topicId AND t1.tagId = 1)
 JOIN tags_topics t2 ON (t.id = t2.topicId AND t2.tagId = 2)
 JOIN tags_topics t3 ON (t.id = t3.topicId AND t3.tagId = 3)

GROUP BY решение:

Обратите внимание, что вам нужно перечислить все столбцы t.* в предложении GROUP BY, если вы не используете MySQL или SQLite.

SELECT t.*
FROM topics t JOIN tags_topics tt 
  ON (t.id = tt.topicId AND tt.tagId IN (1,2,3))
GROUP BY t.id, ...
HAVING COUNT(*) = 3;

Решение подзапроса:

SELECT t.*
FROM topics t
WHERE t.id = ANY (SELECT topicId FROM tags_topics tt WHERE tt.tagId = 1)
  AND t.id = ANY (SELECT topicId FROM tags_topics tt WHERE tt.tagId = 2)
  AND t.id = ANY (SELECT topicId FROM tags_topics tt WHERE tt.tagId = 3);

Модифицировано GROUP BY Решение:

Упрощает предложение GROUP BY, изолируя поиск в подзапросе.

SELECT t.*
FROM topics t
WHERE t.id IN (
  SELECT tt.topicId FROM tags_topics tt 
  WHERE tt.tagId IN (1,2,3))
  GROUP BY tt.id HAVING COUNT(*) = 3
);
3 голосов
/ 15 марта 2009
SELECT 
    topic_id
FROM
    tags_topics
WHERE
    tag_id IN (1,2,3)
GROUP BY
    topic_id
HAVING
    COUNT(*) > 2  /* or use COUNT(*) = 3 if you know that there cannot be duplicates in the junction table */
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...