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
)
Devi avere un UNIQUE
indice su (cat_id, product_id)
(in questo ordine) affinché funzioni velocemente.
Questa soluzione utilizzerà INDEX FOR GROUP BY
per ottenere un elenco di categorie distinte e EXISTS
predicato sarà un po' più veloce di COUNT(*)
(poiché l'aggregazione richiede un sovraccarico).
Se hai più di due prodotti da cercare, regola il primo argomento su LIMIT
di conseguenza.
Dovrebbe essere LIMIT n - 1, 1
, dove n
è il numero di elementi nel IN
elenco.
Aggiornamento:
Per restituire le categorie contenenti tutti i prodotti dell'elenco e nient'altro, utilizza questo:
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)
)