2017-07-19 57 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任何记录。