SELECT cat_id
FROM (
SELECT DISTINCT cat_id
FROM cat_product
) cpo
WHERE EXISTS
(
SELECT NULL
FROM cat_product cpi
WHERE cpi.cat_id = cpo.cat_id
AND product_id IN (2, 3)
LIMIT 1, 1
)
Vous devez avoir un UNIQUE
index sur (cat_id, product_id)
(dans cet ordre) pour que cela fonctionne rapidement.
Cette solution utilisera INDEX FOR GROUP BY
pour obtenir une liste de catégories distinctes, et EXISTS
le prédicat sera un peu plus rapide que COUNT(*)
(puisque l'agrégation nécessite une certaine surcharge).
Si vous avez plus de deux produits à rechercher, ajustez le premier argument à LIMIT
en conséquence.
Il doit être LIMIT n - 1, 1
, où n
est le nombre d'éléments dans le IN
liste.
Mise à jour :
Pour renvoyer les catégories contenant tous les produits de la liste et rien d'autre, utilisez ceci :
SELECT cat_id
FROM (
SELECT DISTINCT cat_id
FROM cat_product
) cpo
WHERE EXISTS
(
SELECT NULL
FROM cat_product cpi
WHERE cpi.cat_id = cpo.cat_id
AND product_id IN (2, 3)
LIMIT 1, 1
)
AND NOT EXISTS
(
SELECT NULL
FROM cat_product cpi
WHERE cpi.cat_id = cpo.cat_id
AND product_id NOT IN (2, 3)
)