J'ai deux tables dans ma base de données:
Produits
ProductTags
Je souhaite sélectionner des produits ayant toutes les balises données. J'ai essayé:
SELECT
*
FROM
Products
JOIN ProductTags ON Products.id = ProductTags.product_id
WHERE
ProductTags.tag_id IN (1, 2, 3)
GROUP BY
Products.id
Mais cela me donne des produits ayant l'une des étiquettes données, au lieu d'avoir toutes les étiquettes données. L'écriture WHERE tag_id = 1 AND tag_id = 2
est inutile, car aucune ligne ne sera renvoyée.
Ce type de problème est connu sous le nom de division relationnelle
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*/
vous devez avoir un groupe par/compter pour vous assurer que tous sont pris en compte
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
MySQL WHERE fieldname IN (1,2,3)
est essentiellement un raccourci pour WHERE fieldname = 1 OR fieldname = 2 OR fieldname = 3
. Donc, si vous n'obtenez pas la fonctionnalité souhaitée avec WHERE ... IN
puis essayez de passer à OR
s. Si cela ne vous donne toujours pas les résultats souhaités, alors peut-être WHERE ... IN
n'est pas la fonction que vous devez utiliser.