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). 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).
It works well, but my SQL query is horrible!
For exemple: if I want to retrieve a list of products that have these 3 attributes (and values), here’s my current SQL query:
- 1st filter: id_attribut = 3 AND value = ‘Lorem ipsum’
- 2nd filter: id_attribut = 4 AND value = ‘Test2’
-
3rd filter: id_attribut = 2 AND value = ‘Bar2’
SELECT products.id FROM products JOIN products_attributs ON products_attributs.id_product = products.id WHERE products_attributs.value = 'Lorem ipsum' AND products_attributs.id_attribut = 3 AND products_attributs.id_product ==> return ID: 25, 27 IN ( SELECT id_product FROM products_attributs WHERE id_attribut = 4 AND value = 'Test2' ==> return ID: 27 AND id_product IN ( SELECT id_product FROM products_attributs WHERE id_attribut = 2 AND value = 'Bar2' ==> return ID: 27 ) )
Result: return ID 27 (this is the only product that corresponds to the three attributes selected by the customer).
It works well but it’s not elegant and not very optimised (imagine if I have more than 10 filters !).
The products_attributs table:
------------------------------------------------- | 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. 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:
Good luck.