Mysql
 sql >> Datenbank >  >> RDS >> Mysql

SQL:Produkte aus einer Kategorie abrufen, müssen sich aber auch in einem anderen Satz von Kategorien befinden

Diese Art von Problem wird als relationale Teilung bezeichnet .

Es gibt zwei gängige Lösungen:

  1. Die erste Lösung reiht die übereinstimmenden Kategorien aneinander und vergleicht sie mit einer festen Zeichenfolge:

    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'
    
  2. Die zweite Lösung führt ein JOIN durch für jeden erforderlichen Wert:

    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) 
    

Ich behandle diese Lösungen in meiner Präsentation SQL-Abfragemuster, optimiert . Ich habe in meinen Tests festgestellt, dass die Join-Lösung für die Leistung viel besser ist.

@Toms Vorschlag ist richtig, so würde das in einer vollständigen Abfrage aussehen:

    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;

Der DISTINCT das @Tom vorschlägt, sollte nicht notwendig sein, da Ihre p2c-Tabelle eine EINZIGARTIGE Einschränkung über (product_id, category_id) haben sollte.