I've inherited a database that has a structure with a table of products, a table consisting of some product attributes and another table to build the relationship between these attributes and a given product.
A user can filter the products by a combination of these attributes, meaning that if more than one attribute is selected only products with all those attributes are returned. Unfortunately, there is now an exception to this rule, whereby a user selecting one of two specific attributes needs results containing either (or both).
The query currently looks like this (not my code):
SELECT DISTINCT p.* FROM products AS p
INNER JOIN attributes a ON p.product_id=a.property_id
WHERE a.attribute_id IN (1,3,7)
GROUP BY p.property_id
HAVING COUNT(DISTINCT a.attribute_id) = 3
I doubt the above is a particularly efficient way of retrieving the required products, but I'm unsure how to proceed in light of the new requirement.
I've now created some php code to construct a special query when the two "special" attributes (3 and 7) are selected:
SELECT DISTINCT p.* FROM products AS p
INNER JOIN attributes a ON p.product_id=a.property_id
WHERE a.attribute_id IN (1,3) OR a.attribute_id IN (1,7)
GROUP BY p.property_id
HAVING COUNT(DISTINCT a.attribute_id) = 2
However, this still does not work as required - any products that share both these attributes are not returned in the result (this is obviously due to the HAVING COUNT clause, but I don't know how I go about fixing it. For clarity, the issue is if 10 products have only attribute 3 but a further five have attributes 3 and 7, the above query will only return the 10 records.
Might it be possible to use some kind of subquery or what alternatives are there?