В дополнение к обычно используемому IN () и использованию счетчика HAVING, я бы заинтересовался разницей в производительности, выполнив множественное объединение следующим образом ...
SELECT STRAIGHT_JOIN
articles.article_id,
articles.title,
articles.body
FROM
categories c1
JOIN articles
on c1.article_id = articles.article_id
JOIN categories c2
on c1.article_id = c2.article_id
AND c2.category_id = 2
JOIN categories c3
on c1.article_id = c3.article_id
AND c3.category_id = 3
WHERE
c1.Category_ID = 1
Да, это может показаться неясным, но давайте подумаем об этом ... сделав ПЕРВЫЕ объединения в таблице категорий, где ОДНА из ваших конкретных категорий - ЭТОТ ПЕРВЫЙ ОТ экземпляра категорий должен быть представителем той категории, которая будет иметь наименьшая зернистость. Пример: Ваши категории «Местные новости», «Видимые» и «Первые» 10. В местных новостях, вероятно, будет больше всего записей, в то время как «Видимые» и «Первые 10» будут иметь еще меньше ... из них, которые будут иметь даже наименьшее количество записей. Используйте ЭТУ категорию в качестве предложения where.
Итак, скажем, у вас есть 100 000 статей и 90 000 в местных новостях, 45 000 в видимых и 12 000 в первых 10. Отправляя запрос только на те из 12 000, вы удаляете большую часть данных.
Путем присоединения к таблице статей и категориям AGAIN в качестве псевдонимов C2 и C3 соответственно на основе других условий, если они найдены, выполнены, если нет, исключены.
Опять же, мне интересно влияние на производительность. Я также хотел бы иметь составной индекс в таблице категорий на обоих (article_id, category_id)