MySQL выберите соединение где и где - PullRequest
9 голосов
/ 16 февраля 2011

В моей базе данных две таблицы:

Продукты

  • id (int, первичный ключ)
  • имя (варчар)

ProductTags

  • product_id (int)
  • tag_id (int)

Я бы хотел выбрать товары со всеми заданными тегами. Я попробовал:

SELECT
    *
FROM
    Products
JOIN ProductTags ON Products.id = ProductTags.product_id
WHERE
    ProductTags.tag_id IN (1, 2, 3)
GROUP BY
    Products.id

Но это дает мне продукты, имеющие любой из указанных тегов, вместо того, чтобы иметь все заданные теги. Запись WHERE tag_id = 1 AND tag_id = 2 не имеет смысла, потому что строки не будут возвращены.

Ответы [ 3 ]

16 голосов
/ 16 февраля 2011

Этот тип проблемы известен как реляционное деление

SELECT Products.* 
FROM Products
JOIN ProductTags ON Products.id = ProductTags.product_id
WHERE ProductTags.tag_id IN (1,2,3)
GROUP BY Products.id /*<--This is OK in MySQL other RDBMSs 
                          would want the whole SELECT list*/

HAVING COUNT(DISTINCT ProductTags.tag_id) = 3 /*Assuming that there is a unique
                                              constraint on product_id,tag_id you 
                                              don't need the DISTINCT*/
0 голосов
/ 16 февраля 2011

MySQL WHERE fieldname IN (1,2,3) по сути является сокращением для WHERE fieldname = 1 OR fieldname = 2 OR fieldname = 3. Так что если вы не получаете нужную функциональность с WHERE ... IN, попробуйте переключиться на OR s. Если это все еще не дает желаемых результатов, то, возможно, WHERE ... IN не та функция, которую вам нужно использовать.

0 голосов
/ 16 февраля 2011

вам нужно иметь группу по / count, чтобы гарантировать, что все учитываются

select Products.*
  from Products 
         join ( SELECT Product_ID
                  FROM ProductTags
                  where ProductTags.tag_id IN (1,2,3)
                  GROUP BY Products.id
                  having count( distinct tag_id ) = 3 ) PreQuery
        on ON Products.id = PreQuery.product_id 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...