2017-07-19 56 views
3

我有以下表搜索在MySQL查詢多個屬性(與工作示例)

表:產品

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

表:屬性

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

表: attribute_values

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

和我有以下查詢的:(!WORKS)

查詢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')) 
       ) 

查詢2(不工作!)

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')) 
        ) 

正如你所看到的,2個查詢之間的差異在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')) 
    ) 

我在查詢一個只搜索品牌>三星,查詢2的品牌>三星和顏色>藍色。

有誰知道爲什麼我的第二個查詢不起作用?

+0

你想達到什麼目的?在where子句中有4個條件,並且在同一列上用AND連接兩次。查詢不會返回任何結果,因爲它無法找到name ='brand'和name ='color'或value ='samsung'和value ='blue'的內容。 即使你寫了一個簡單的選擇屬性表,如 select * from屬性where name ='brand'和name ='color',它將總是返回空。 – money

+0

我試圖找到所有電話品牌=三星和顏色=藍色,這就是我「試圖」做的。 –

+0

我認爲你應該以更好的方式重新設計你的表格,而不是讓這個查詢工作。 – money

回答

1

我還沒有足夠的聲望來評論stackoverflow,但我認爲表c從來沒有宣佈,所以我刪除它。這是我發現用你的代碼解決你的問題的方法。

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' 
      ) 
     ) 

所以基本上你應該首先使一個過濾器層出不窮,不能同時在同一時間,沒有ATTRIBUTE_VALUE是藍色和三星。希望這可以幫助

1

看看你WHERE條件second查詢:

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

這種情況最終是類似於:

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

,這將NEVER將是TRUE任何記錄。