MySQL Seleziona Iscriviti dove e dove
-
14-11-2019 - |
Domanda
Ho due tabelle nel mio database:
Prodotti
- .
- ID (INT, PRIMARY KEY)
- Nome (varchar)
ProductTags
- .
- Prodotto_id (int)
- tag_id (int)
Vorrei selezionare prodotti aventi tutti i tag dati.Ho provato:
.SELECT * FROM Products JOIN ProductTags ON Products.id = ProductTags.product_id WHERE ProductTags.tag_id IN (1, 2, 3) GROUP BY Products.id
Ma mi dà prodotti che hanno uno dei tag determinati, invece di avere tutti i tag dati.Scrivere
WHERE tag_id = 1 AND tag_id = 2
è inutile, perché non verranno restituite righe.
Soluzione
This type of problem is known as relational division
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*/
Altri suggerimenti
you need to have a group by / count to ensure all are accounted for
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
The MySQL WHERE fieldname IN (1,2,3)
is essentially shorthand for WHERE fieldname = 1 OR fieldname = 2 OR fieldname = 3
. So if you aren't getting the desired functionality with WHERE ... IN
then try switching to OR
s. If that still doesn't give you the results you want, then perhaps WHERE ... IN
is not the function you need to use.