Reputation: 11
I need to get all products from product_attributes table where I have several pairs of attribute id and filter text value.
It is made harder because text is stored as array separated by ;
.
TABLE product_attribute
Fields product_id, attribute_id, text
SELECT pa.product_id FROM product_attribute as pa
WHERE (
(pa.attribute_id = '15' AND pa.text LIKE '%Male%' )
AND
(pa.attribute_id = '12' AND pa.text LIKE '%Cream%' )
)
Obviously this does not work, because attribute_id cant be 12 and 15 same time.
And I cannot use OR here because it will return all products (all male) + (all cream)
and I need only intersection (male cream)
Got answer here. Alternative to Intersect in MySQL
My variant:
SELECT paz.product_id
FROM (
( SELECT product_id FROM oc_product_attribute WHERE attribute_id = '15' AND text LIKE '%male%' )
UNION ALL
( SELECT product_id FROM oc_product_attribute WHERE attribute_id = '12' AND text LIKE '%creme%' )
) paz GROUP BY paz.product_id HAVING COUNT(*)=2
And Gordon Linoff variant^
SELECT pa.product_id
FROM product_attribute pa
GROUP BY pa.product_id
HAVING SUM(pa.attribute_id = '15' AND pa.text LIKE '%Male%') > 0 AND
SUM(pa.attribute_id = '12' AND pa.text LIKE '%Cream%');
Upvotes: 1
Views: 1633
Reputation: 1270483
I often approach these using group by
and having
:
SELECT pa.product_id
FROM product_attribute pa
GROUP BY pa.product_id
HAVING SUM(pa.attribute_id = '15' AND pa.text LIKE '%Male%') > 0 AND
SUM(pa.attribute_id = '12' AND pa.text LIKE '%Cream%') > 0;
Each condition in the HAVING
clause verifies that there is at least one row meeting the particular condition.
Upvotes: 1
Reputation: 722
SELECT pa.product_id FROM product_attribute as pa
WHERE
(pa.attribute_id = '15' AND pa.text LIKE '%Male%' )
union
SELECT pa.product_id FROM product_attribute as pa
WHERE
(pa.attribute_id = '12' AND pa.text LIKE '%Male%' )
combine with union...
you also can do everything together and distinct the results
select a.* from
(select * from product_attribute where pa.attribute_id = '15' or
pa.attribute_id = '12') as a
where a.text LIKE '%Male%' or a.text = '%Cream%'
Upvotes: 0
Reputation: 64476
If you have only 2 attributes to compare then use a self join to product_attribute
SELECT
pa.product_id
FROM
product_attribute AS pa
JOIN product_attribute AS pa1 USING (product_id)
WHERE pa.attribute_id = '15'
AND pa.text LIKE '%Male%'
AND pa1.attribute_id = '12'
AND pa1.text LIKE '%Cream%'
Another way would be using COUNT/GROUP BY /HAVING
SELECT
pa.product_id
FROM
product_attribute AS pa
WHERE pa.attribute_id IN ('15', '12')
AND (
pa.text LIKE '%Male%'
OR pa.text LIKE '%Cream%'
)
GROUP BY pa.product_id
HAVING COUNT(DISTINCT pa.attribute_id) = 2
Upvotes: 0