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
)
Трябва да имате UNIQUE
индекс на (cat_id, product_id)
(в този ред), за да работи бързо.
Това решение ще използва INDEX FOR GROUP BY
за да получите списък с отделни категории и EXISTS
предикатът ще бъде малко по-бърз от COUNT(*)
(тъй като агрегирането изисква някои допълнителни разходи).
Ако имате повече от два продукта за търсене, коригирайте първия аргумент на LIMIT
съответно.
Трябва да е LIMIT n - 1, 1
, където n
е броят на елементите в IN
списък.
Актуализация:
За да върнете категориите, съдържащи всички продукти от списъка и нищо друго, използвайте това:
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)
)