[英]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查询:
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.