有EXISTS和GROUP BY的麻烦

时间:2016-12-08 17:47:26

标签: mysql exists

我已经用了一段时间才能找到灵魂,所以也许你可以帮助我。

我有一个包含3列' id' '产品' '代码',产品可以重复,但每个产品的代码必须是唯一的。这是表格的结构:

CREATE TABLE table1
    (`id` int, `product` varchar(10), `code` int)
;

INSERT INTO table1
    (`id`, `product`, `code`)
VALUES
    (1, 'product1', 1),
    (2, 'product1', 2),
    (3, 'product1', 3),
    (4, 'product2', 2),
    (5, 'product2', 3),
    (6, 'product3', 1),
    (7, 'product3', 3)
;

所以我想要做的是一个案例列表,如果产品有代码1和代码2,在响应列中显示某个值,如果产品只有代码1显示另一个值,如果产品有代码2然后是其他值,如果产品既没有代码1也没有代码2,则显示另一个值(代码3在此示例中无关紧要)。

这就是我到目前为止所做的事情

select product, 
    case 
    when exists(select 1 from table1 where code=1) = 1
        and exists(select 1 from table1 where code=2) = 1
    then 'Types are  : 1,2'
    when exists(select 1 from table1 where code=1) = 1
        and exists(select 1 from table1 where code=2) = 0
    then 'Type is  : 1'
    when exists(select 1 from table1 where code=1) = 0
        and exists(select 1 from table1 where code=2) = 1
    then 'Type is  : 2'
    else
        'There are no types 1 or 2'
    end as response
from table1
group by product

问题是结果集只显示'类型是:1,2'在我的product1,product2和product3的响应列中,我相信在subselect中搜索所有产品(而不是每个产品),所以始终存在代码1和代码2。

非常欢迎您提供的任何帮助或指示。

感谢阅读。

小提琴示例:http://sqlfiddle.com/#!9/25eb55/3

1 个答案:

答案 0 :(得分:3)

您的子查询正在整个表中搜索您感兴趣的代码,而不仅仅是具有相同产品的行。

如果希望仅针对具有相同产品的行评估子查询,则需要使用相关子查询

select p.product, 
    case 
    when exists(select 1 from table1 where code=1 and product=p.product) = 1
        and exists(select 1 from table1 where code=2 and product=p.product) = 1
    then 'Types are  : 1,2'
    when exists(select 1 from table1 where code=1 and product=p.product) = 1
        and exists(select 1 from table1 where code=2 and product=p.product) = 0
    then 'Type is  : 1'
    when exists(select 1 from table1 where code=1 and product=p.product) = 0
        and exists(select 1 from table1 where code=2 and product=p.product) = 1
    then 'Type is  : 2'
    else
        'There are no types 1 or 2'
    end as response
from table1 as p
group by product

输出:

+----------+------------------+
| product  | response         |
+----------+------------------+
| product1 | Types are  : 1,2 |
| product2 | Type is  : 2     |
| product3 | Type is  : 1     |
+----------+------------------+

但是,我通常会避免使用相关子查询,因为它们的性能代价很高。 MySQL必须为外部查询中的每一行重新执行子查询。

这是一个替代查询,它不使用子查询但给出相同的结果:

SELECT product,
  CASE GROUP_CONCAT(CASE WHEN code IN (1,2) THEN code ELSE NULL END ORDER BY code)
  WHEN '1' THEN 'Type is  : 1'
  WHEN '1,2' THEN 'Types are: 1,2'
  WHEN '2' THEN 'Type is  : 2'
  ELSE 'There are no types 1 or 2'
  END AS response
FROM table1
GROUP BY product