2017-07-19 5 views
3

Ich habe die folgenden TabellenSuche nach mehreren Attributen in Abfrage MySQL (mit Arbeitsbeispiel)

Tabelle: Produkte

+------------+--------------------+ 
| product_id | name    | 
+------------+--------------------+ 
| 1   | samsung galaxy s8 | 
| 2   | apple iphone 7  | 
+------------+--------------------+ 

Tabelle:

+--------------+--------------------+ 
| attribute_id | name    | 
+--------------+--------------------+ 
| 1   | brand    | 
| 2   | color    | 
+--------------+--------------------+ 

Tabelle Attribute: Attributwerte

+--------------------+--------------+------------+---------------------+ 
| attribute_value_id | attribute_id | product_id | value    | 
+--------------------+--------------+------------+---------------------+ 
| 1     | 1   | 1   | samsung    | 
| 2     | 2   | 1   | blue    | 
| 3     | 1   | 2   | apple    | 
| 4     | 2   | 2   | red     | 
+--------------------+--------------+------------+---------------------+ 

Und ich habe die folgende Abfrage: (! WORKS)

Abfrage 1

SELECT 
       p.product_id    AS product_id, 
       p.name      AS product_name, 
       v.value      AS attribute_value, 
       a.attribute_id    AS attribute_id, 
       a.name      AS attribute_name, 
       c.name      AS attributes_category_name 
    FROM 
       products p 
    LEFT JOIN 
       attribute_values v USING (product_id) 
    LEFT JOIN 
       attributes a USING (attribute_id) 
    WHERE 
       p.product_id IN (
        SELECT 
         p.product_id 
        FROM 
         products p 
        LEFT JOIN 
         attribute_values v USING (product_id) 
        LEFT JOIN 
         attributes a USING (attribute_id) 
        WHERE 
         (a.name = 'brand' AND (v.value = 'samsung')) 
       ) 

Abfrage 2 (funktioniert nicht!)

SELECT 
       p.product_id    AS product_id, 
       p.name      AS product_name, 
       v.value      AS attribute_value, 
       a.attribute_id    AS attribute_id, 
       a.name      AS attribute_name, 
       c.name      AS attributes_category_name 
    FROM 
       products p 
    LEFT JOIN 
       attribute_values v USING (product_id) 
    LEFT JOIN 
       attributes a USING (attribute_id) 
    WHERE 
       p.product_id IN ( 
        SELECT 
         p.product_id 
        FROM 
         products p 
        LEFT JOIN 
         attribute_values v USING (product_id) 
        LEFT JOIN 
         attributes a USING (attribute_id) 
        WHERE 
         (a.name = 'brand' AND (v.value = 'samsung')) 
         AND (a.name = 'color' AND (v.value = 'blue')) 
        ) 

Wie Sie sehen können, liegt der Unterschied zwischen den beiden Abfragen im WHER E-Clausule.

Query 1: 
-------- 
p.product_id IN (
    SELECT 
     p.product_id 
    FROM 
     products p 
    LEFT JOIN 
     attribute_values v USING (product_id) 
    LEFT JOIN 
     attributes a USING (attribute_id) 
    WHERE 
     (a.name = 'brand' AND (v.value = 'samsung')) 
    ) 

Query 2: 
-------- 
p.product_id IN (
    SELECT 
     p.product_id 
    FROM 
     products p 
    LEFT JOIN 
     attribute_values v USING (product_id) 
    LEFT JOIN 
     attributes a USING (attribute_id) 
    WHERE 
     (a.name = 'brand' AND (v.value = 'samsung')) 
     AND (a.name = 'color' AND (v.value = 'blue')) 
    ) 

Ich suche in Abfrage einer nur für die Marke> Samsung, in Abfrage 2 für die Marke> Samsung und Farbe> Blau.

Weiß jemand, warum meine zweite Abfrage nicht funktioniert?

+0

Was versuchen Sie zu erreichen? Sie haben 4 Bedingungen in Ihrer where-Klausel, die zweimal mit AND in denselben Spalten verknüpft sind. Die Abfrage gibt kein Ergebnis zurück, da sie nichts mit name = 'brand' und name = 'color' oder value = 'samsung' und value = 'blue' finden kann. Auch wenn Sie eine einfache Auswahl in Ihrer Attributtabelle schreiben, so etwas wie wählen Sie * aus den Attributen wo Name = 'Marke' und Name = 'Farbe', es wird immer leer zurückgegeben. – money

+0

Ich versuche, alle Telefone zu finden, wo Marke = Samsung UND Farbe = Blau, das ist was ich "versuche" zu tun. –

+0

Ich denke, Sie sollten Ihre Tabellen besser umgestalten, anstatt diese Abfrage zu aktivieren. – money

Antwort

1

Ich habe immer noch nicht den Ruf genug, um Stackoverflow zu kommentieren, aber ich denke, die Tabelle c wird nie deklariert, also entferne ich sie. So habe ich Ihr Problem mit Ihrem Code gelöst.

SELECT 
      p.product_id    AS product_id, 
      p.name      AS product_name, 
      v.value      AS attribute_value, 
      a.attribute_id    AS attribute_id, 
      a.name      AS attribute_name/*, 
      c.name      AS attributes_category_name*/ 
FROM 
      products p 
LEFT JOIN 
      attribute_values v USING (product_id) 
LEFT JOIN 
      attributes a USING (attribute_id) 
WHERE 
      p.product_id IN ( 
       SELECT 
       p2.product_id 
       FROM 
       products p2 
       LEFT JOIN 
       attribute_values v USING (product_id) 
       LEFT JOIN 
       attributes a USING (attribute_id) 
       WHERE 
       a.name = 'brand' AND v.value = 'samsung' and p2.product_id IN (
        SELECT 
        p3.product_id 
        FROM 
        products p3 
        LEFT JOIN 
        attribute_values v USING (product_id) 
        LEFT JOIN 
        attributes a USING (attribute_id) 
        WHERE a.name = 'color' AND v.value = 'blue' 
      ) 
     ) 

so dass im Grunde sollten Sie zunächst einen Filter nach dem anderen machen, nicht beide zur gleichen Zeit gibt es keine attribute_value, die blau und ein Samsung ist. Hoffe, das hilft

1

Sehen Sie sich Ihre WHERE Zustand in second Abfrage:

WHERE 
    (a.name = 'brand' AND (v.value = 'samsung')) 
    AND (a.name = 'color' AND (v.value = 'blue')) 

Dieser Zustand ist letztlich ähnlich wie:

WHERE a.name = 'brand' AND v.value = 'samsung' 
    AND a.name = 'color' AND v.value = 'blue' 

und dies wird NEVER gehen TRUE für jeden Datensatz sein.

Verwandte Themen