Intereting Posts
PHP SoapClient: несколько сложных типов перезаписываются в soapcall Проверка продуктов в корзине по названию категории woocommerce? Facebook Graph API не даст мне данные изображения php для получения всех понедельников в диапазоне дат как проверить, зарегистрирован ли пользователь на его сеансе в маршруте, а затем вызвать метод контроллера в laravel? Что такое S и W в тестовом выходе PHPUnit? Доступ к переменной из раскрывающегося списка jquery? phpdoc: Каков правильный способ документирования константы PHP Mail приводит к ошибке: «заголовок отсутствует» Прыжок во времени во время работы PHP () Как реализовать «запомнить меня» в laravel 5.1? Регулярное выражение, замените множественные слэши только одним Пример атаки CSRF (кросс-сайт запроса) и предотвращение в PHP PHPEXCEL получает форматированную дату, как видно в файле excel Использование SimpleHtmlDom, как удалить и заменить определенный атрибут

mysql имеет все значения

Это относится к моему последнему запросу mysql-запроса с AND, OR и NOT

Вместо того, чтобы редактировать вопрос, я задаю новый вопрос, потому что вопрос является лишь частью предыдущего вопроса с изменением.

Я ищу сделать mysql-запрос, который возвращает мне все статьи, в которых есть все необходимые темы.

Article id .... Topic id .... ArticleTopics article_id topic_id type 

что бы эффективно делало:

 SELECT * FROM Article LEFT JOIN ArticleTopics ON Article.id = ArticleTopics.article_id WHERE ArticleTopics.topic_id HAS ALL (these topics) 

Это возможно? Каков наилучший подход для этого?

Некоторые из других ответов предполагают использование псевдонимов в дочерней таблице для каждой статьи фильтра – это может быть не очень эффективно или хорошо масштабироваться.

Рассматривать:

 SELECT x.* FROM Article x INNER JOIN (SELECT t.article_id, COUNT(t.article_id) FROM articleTopics t WHERE t.topic_id IN ([your_list_of_topics]) GROUP BY t.article_id HAVING COUNT(t.article_id)>=[number of elements in [your_list_of_topics]] ORDER BY COUNT(t.article_id) DESC LIMIT 0,100) AS ilv ON x.id=ilv.article_id 

Другим преимуществом этого подхода является то, что структура запроса не нуждается в изменении с количеством тем, которые вы ищете, – вы даже можете поместить их во временную таблицу и выполнить соединение вместо использования «IN (.. .) 'литерал.

Вам нужно попробовать, чтобы увидеть, какой запрос ведет себя лучше.

Это делается с использованием нескольких соединений с одной и той же таблицей.

Чтобы выбрать все статьи, в которых есть темы с идентификаторами 1, 2 и 3, вам нужно сделать:

 SELECT * FROM Article a INNER JOIN ArticleTopics at1 ON a.id = at1.article_id AND at1.topic_id = 1 INNER JOIN ArticleTopics at2 ON a.id = at2.article_id AND at2.topic_id = 2 INNER JOIN ArticleTopics at3 ON a.id = at3.article_id AND at3.topic_id = 3 

// EDIT Исправлено. Добавлены псевдонимы таблицы; Должно быть, я слишком долго работал с хорошими решениями ORM …

 SELECT * FROM Article WHERE (SELECT COUNT(*) FROM ArticleTopics WHERE Article.id = ArticleTopics.article_id AND ArticleTopics.topic_id=1) > 0 AND (SELECT COUNT(*) FROM ArticleTopics WHERE Article.id = ArticleTopics.article_id AND ArticleTopics.topic_id=2) > 0 AND (SELECT COUNT(*) FROM ArticleTopics WHERE Article.id = ArticleTopics.article_id AND ArticleTopics.topic_id=3) > 0 AND ...