I need to filter products where certain attributes are stored in a joined table that match all the required properties, i.e. users need to be able to gradually narrow down their search by adding requirements.
The problem really just concerns the properties table I think, rather than the join, given the following (simplified) table of product properties:
id product_id property value --------------------------------- 1 1 color red 2 1 size small 3 2 color red 4 2 size large
how would I get all the product_ids where value is both 'red' and 'small' ?
A similar question was asked before but not answered very fully. A solution involves a COUNT and HAVING to get the rows where there are as many rows in each group as required values e.g.
SELECT product_id, count(*) AS group_count FROM properties where
value = 'red' OR value = 'small'
GROUP BY product_id
HAVING group_count = 2
This works but I'm concerned about performance, it seems like there would be a better way.
Eventually this would need to be joined with, or at least used to filter the products table:
id name ------------- 1 Product 1 2 Product 2
I forgot to mention that I have 2 of these properties tables joined to products that I need to filter on, one with regular attributes of a product, another with available configurable options (a bit like variants). The scenario is to allow users to filter products like: "show products where gender = 'male', brand = 'nike' and size == 'small'" where gender and brand are 'properties' and size is in options (configurable when adding to cart)
The solution of using a group with a count works with the 2 joined tables still but it gets messy, the required group count is the number of required options on the first table multiplied by the number on the second.
I could just fetch the ids from properties (and the other table) then just do a select where id IN(ids), matching a set of ids for both property tables, I don't like the idea of doing this with a really long list of ids though.