MySQL查询仅在加入

时间:2015-06-03 10:13:43

标签: mysql database

我正在努力完成某项工作,基本上归结为: 我想要检索所有产品并显示该产品所属的所有类别。但是,我想过滤出类别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:此查询将在大型数据库上运行,因此查询越快越好。

3 个答案:

答案 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