Dit type probleem wordt relationele verdeling genoemd .
Er zijn twee veelvoorkomende oplossingen:
-
De eerste oplossing voegt de overeenkomende categorieën samen en vergelijkt deze met een vaste tekenreeks:
SELECT p2c.product_id FROM oc_product_to_category p2c GROUP BY p2c.product_id HAVING GROUP_CONCAT(p2c.category_id SEPARATOR ',' ORDER BY p2c.category_id) = '1,2'
-
Tweede oplossing doet een
JOIN
voor elke vereiste waarde:SELECT p.product_id FROM oc_product p INNER JOIN oc_product_to_category p2c1 ON (p.product_id = p2c1.product_id AND p2c1.category_id = 1) INNER JOIN oc_product_to_category p2c2 ON (p.product_id = p2c2.product_id AND p2c2.category_id = 2)
Ik behandel deze oplossingen in mijn presentatie SQL-querypatronen, geoptimaliseerd . Ik ontdekte tijdens mijn tests dat de join-oplossing veel beter is voor de prestaties.
De suggestie van @Tom is juist, dit is hoe dat eruit zou zien in een volledige zoekopdracht:
SELECT p.product_id, GROUP_CONCAT(p2c3.category_id SEPARATOR ',') AS categories
FROM oc_product p
INNER JOIN oc_product_to_category p2c1
ON (p.product_id = p2c1.product_id AND p2c1.category_id = 1)
INNER JOIN oc_product_to_category p2c2
ON (p.product_id = p2c2.product_id AND p2c2.category_id = 2)
INNER JOIN oc_product_to_category p2c3
ON (p.product_id = p2c3.product_id)
GROUP BY p.product_id;
De DISTINCT
dat @Tom suggereert zou niet nodig moeten zijn, omdat je p2c-tabel een UNIEKE beperking zou moeten hebben over (product_id, category_id).