我正在努力完成某项工作,基本上归结为: 我想要检索所有产品并显示该产品所属的所有类别。但是,我想过滤出类别x和y中存在的产品。
所以,这是我的问题:
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;
这很好用,我得到的结果如下:
p.id | p.name | category
10 | example| 15,16,17
11 | example| 15,20
12 | example| 39,40
显然'15,16,16'是产品所在的类别。但是,现在我想过滤仅包含类别15或16的产品的结果集。所以我想得到的结果集是:
p.id | p.name | category
10 | example| 15,16,17
11 | example| 15,20
所以,我尝试的是在我的MySQL语句中添加一个WHERE,如下所示:
WHERE category IN (15,16)
这适用于过滤,但问题是,在结果集中我不知道产品还在哪个其他类别。所以我看到的结果是:
p.id | p.name | category
10 | example| 15,16
11 | example| 15
注意与所需结果的区别在于我只看到过滤后的猫而不是所有的猫。
我确实知道为什么它的行为原样,因为我的结果集中的'category'列显然是基于过滤后的值。但是,我不知道如何解决这个问题,或者我想要的是什么。
PS:此查询将在大型数据库上运行,因此查询越快越好。
答案 0 :(得分:0)
尝试这个未经测试的查询:
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
答案 1 :(得分:0)
一个(公认的很奇怪)选项是在汇总结果上使用find_in_set
:
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
答案 2 :(得分:0)
我只是想知道我将如何解决这个任务:
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,',','|'),')([[:>:]])'));
传递HAVING子句之前的组:
p.id | p.name | category
10 | example| 15,16,17
11 | example| 15,20
12 | example| 39,40
然后我们使用HAVING子句和REGEXP检查组:
HAVING REGEXP_INSTR(t3.category, CONCAT('[[:<:]](15|16)[[:>:]]'))
/* REGEX: START_WORD_BOUNDARY(15 OR 16)END_WORD_BOUNDARY */
这里是:
p.id | p.name | category
10 | example| 15,16,17
11 | example| 15,20