I'm trying to get something done, basically it comes down to this: I want to retrieve all products and show all categories this product is in. But then, I want to filter out only the products which exists in categories x and y.
So, this is my query:
SELECT p.id, p.name,GROUP_CONCAT(distinct(pc.category_id) SEPARATOR ", ") as category
FROM products p
LEFT JOIN product_category pc ON p.id = pc.productid
GROUP BY p.id;
This works great, I get result like this:
p.id | p.name | category
10 | example| 15,16,17
11 | example| 15,20
12 | example| 39,40
Obviously the '15,16,16' are the categories the product is in. However, now I want to filter the resultset on products only containing category 15 or 16. So the resultset I want to get is:
p.id | p.name | category
10 | example| 15,16,17
11 | example| 15,20
So, what I tried is adding a WHERE to my MySQL statement like this:
WHERE category IN (15,16)
This works as for the filtering, but the problem is, in the resultset I don`t see which other categories the product is also in. So the result I see is:
p.id | p.name | category
10 | example| 15,16
11 | example| 15
Note the difference with the desired result is I just see the filtered cats and not all the cats.
I do get why this is behaving as it is, since obviously the 'category' column in my resultset is based on the values after filtering. However, I don`t know how to work around this or if what I want is even possible.
PS: this query will run on huge databases so the faster the query, the better.
Try this untested query:
select * p.id, p.name,GROUP_CONCAT(distinct(pc.category_id) SEPARATOR ", ") as category
from FROM products p
LEFT JOIN product_category pc ON p.id = pc.productid
where p.id in (
SELECT pc.productid
product_category pc ON p.id = pc.productid
where category IN (15,16)
GROUP BY pc.productid
)
GROUP BY p.id
One (admittedly weird) option is to use find_in_set
on the aggregate result:
SELECT p.id,
p.name,
GROUP_CONCAT(DISTINCT(pc.category_id) SEPARATOR ", ") AS category
FROM products p
LEFT JOIN product_category pc ON p.id = pc.productid
GROUP BY p.id
HAVING FIND_IN_SET('15', GROUP_CONCAT (pc.category_id)) > 0 OR
FIND_IN_SET('16', GROUP_CONCAT (pc.category_id)) > 0
I was just wondering how would I resolved this task:
SET @needle = '15,16';
SELECT p.id, p.name, GROUP_CONCAT(pc.category_id SEPARATOR ', ') AS 'category' FROM products p
LEFT JOIN product_category pc ON p.id = pc.productid GROUP BY id
HAVING REGEXP_INSTR(GROUP_CONCAT(pc.category_id), CONCAT('([[:<:]])(',REPLACE(@needle,',','|'),')([[:>:]])'));
The groups before passing the HAVING clause:
p.id | p.name | category
10 | example| 15,16,17
11 | example| 15,20
12 | example| 39,40
Then we check the groups with the HAVING clause and REGEXP:
HAVING REGEXP_INSTR(t3.category, CONCAT('[[:<:]](15|16)[[:>:]]'))
/* REGEX: START_WORD_BOUNDARY(15 OR 16)END_WORD_BOUNDARY */
And here it is:
p.id | p.name | category
10 | example| 15,16,17
11 | example| 15,20
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.