凌乱的自我加入Mysql SELECT

时间:2012-02-02 12:43:43

标签: mysql sql

我需要返回一个产品ID列表......

  1. 在特定类别(例如“服装”)
  2. 具有各种属性,例如“红色”或“绿色”
  3. 它们本身位于属性'群组'中,例如'Color'
  4. 当我需要在MULTIPLE属性组中选择MULTIPLE属性选项时,我遇到了困难。例如,如果我需要返回颜色为“蓝色”或“红色”的产品列表,则尺寸为“中”或“XXL”。

    这是我的代码:

    SELECT `products.id` 
    FROM 
    `products` , 
    `categories` ,
    `attributes` att1, 
    `attributes` att2   
    WHERE products.id = categories.productid 
    AND `categories.id` = 3 
    AND att1.productid = products.id
    AND att1.productid = att2.productid
    AND 
    (att1.attributeid = 58 OR att1.attributeid = 60)
    AND 
    (att2.attributeid = 12 OR att2.attributeid = 9)
    

    我相信这段代码有效,但看起来很乱,我不确定我的'脏'自我加入是不是正确的方法。有没有人对我的问题更“优雅”的解决方案有任何想法?

2 个答案:

答案 0 :(得分:5)

请使用现代连接语法:

SELECT products.id
FROM products 
join categories on products.id = categories.productid
join attributes att1 on att1.productid = products.id 
join attributes att2 on att1.productid = att2.productid
WHERE categories.id = 3 
AND att1.attributeid IN (58, 60)
AND att2.attributeid IN (12, 9)

它更容易阅读,因为它明显地从行过滤条件中加入条件。 SQL优化器也更容易识别这些区别并创建更好的查询计划

被修改

我alsp添加了IN (...)的使用。它不仅看起来更好,数据库将使用IN的索引,但通常 OR,即使它们的含义相同

答案 1 :(得分:4)

SELECT p.id 
FROM   products p
JOIN   categories  c ON  c.productid = p.id
JOIN   attributes a1 ON a1.productid = p.id
JOIN   attributes a2 ON a2.productid = p.id
WHERE  categories.id = 3 
AND    a1.attributeid IN (58, 60)
AND    a2.attributeid IN (12,  9)

我认为您将第二个属性加入第一个属性而不是将其加入产品时出错。我解决了这个问题。

第二个想法,这可能是故意的,我的纠正错了。但是,将属性与属性组混合在同一个表中是一种混乱的设计。

我还简化了语法并使用了更具可读性的显式JOIN。

相关问题