简体   繁体   English

使用多个IN子查询改进SQL查询(按属性系统过滤)

[英]Improve SQL query with multiple IN sub-query (filter by attribute system)

I have a product catalog with a attribute system. 我有一个带有属性系统的产品目录。

I want to create a system that will allow client to browse products by attribute (like on Magento). 我想创建一个系统,使客户可以按属性浏览产品(例如在Magento上)。 So, I am trying to programatically retrieve a list of products (by ID return) that have a attribute with a specific value (or many attributes with many specific values). 因此,我试图以编程方式检索具有属性(具有特定值)(或具有许多特定值的许多属性)的产品列表(通过ID返回)。

It works well, but my SQL query is horrible! 它运作良好,但是我的SQL查询太可怕了!

For exemple: if I want to retrieve a list of products that have these 3 attributes (and values), here's my current SQL query: 例如:如果我要检索具有这3个属性(和值)的产品列表,这是我当前的SQL查询:

  • 1st filter: id_attribut = 3 AND value = 'Lorem ipsum' 第一个过滤器:id_attribut = 3 AND value ='Lorem ipsum'
  • 2nd filter: id_attribut = 4 AND value = 'Test2' 第二个过滤器:id_attribut = 4 AND value ='Test2'
  • 3rd filter: id_attribut = 2 AND value = 'Bar2' 第三个过滤器:id_attribut = 2 AND value ='Bar2'

     SELECT products.id SELECT products.id\nFROM products 从产品\nJOIN products_attributs ON products_attributs.id_product = products.id 加入products_attributs ON products_attributs.id_product = products.id\nWHERE products_attributs.value = 'Lorem ipsum' WHERE products_attributs.value ='Lorem ipsum'\nAND products_attributs.id_attribut = 3 AND products_attributs.id_attribut = 3\nAND products_attributs.id_product ==> return ID: 25, 27 AND products_attributs.id_product ==>返回ID:25、27\nIN ( IN(\n    SELECT id_product 选择id_product\n    FROM products_attributs FROM products_attributs\n    WHERE id_attribut = 4 在哪里id_attribut = 4\n    AND value = 'Test2' ==> return ID: 27 AND值='Test2'==>返回ID:27\n    AND id_product IN ( AND id_product IN(\n        SELECT id_product 选择id_product\n        FROM products_attributs FROM products_attributs\n        WHERE id_attribut = 2 在哪里id_attribut = 2\n        AND value = 'Bar2' ==> return ID: 27 AND值='Bar2'==>返回ID:27\n    ) \n)  

Result: return ID 27 (this is the only product that corresponds to the three attributes selected by the customer). 结果:返回ID 27(这是与客户选择的三个属性相对应的唯一产品)。

It works well but it's not elegant and not very optimised (imagine if I have more than 10 filters !). 它运作良好,但不是很优雅,也不是很优化(想想如果我有10个以上的滤镜!)。

The products_attributs table: products_attributs表:

-------------------------------------------------
| id | id_product | id_attribut | value         |
-------------------------------------------------
| 1  | 25         | 1           | Foo           |
| 2  | 25         | 2           | Bar           |
| 3  | 25         | 3           | Lorem ipsum   |
| 4  | 25         | 4           | Test          |
| 5  | 27         | 1           | Foo2          |
| 6  | 27         | 2           | Bar2          |
| 7  | 27         | 3           | Lorem ipsum   |
| 8  | 27         | 4           | Test2         |
| 9  | 28         | 1           | ... etc       |
-------------------------------------------------

How can I improve that? 我该如何改善呢?

Thank a lot! 非常感谢!

The only way to have "nice" SQL is to make columns for all of your attributes. 使用“ nice” SQL的唯一方法是为所有属性创建列。 That's much harder to maintain, so I wouldn't recommend it. 这很难维护,所以我不建议这样做。

Given than, you can join back to your attributes table multiple times, like this: 给定的比,您可以多次连接回属性表,如下所示:

SELECT p.id
FROM products p
LEFT OUTER JOIN products_attributs pa1 ON pa1.id_product = p.id and pa1.value = 'Lorem ipsum' AND pa1.id_attribut = 3
LEFT OUTER JOIN products_attributs pa2 ON pa2.id_product = p.id and pa2.value = 'Test2' AND pa1.id_attribut = 4
LEFT OUTER JOIN products_attributs pa3 ON pa3.id_product = p.id and pa3.value = 'Bar2' AND pa1.id_attribut = 2

Good luck. 祝好运。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM