思路:
思路1:买了A,买了B,没有买C。
按人分组统计,A的数>0, B的数>0 ,C的数 = 0。
思路2:反过来查,用户id。在产品表里,产品名为A,为B的用户列表里,但是不在产品表里,产品为C的用户列表里。
错误答案:
select c.customer_id,c.customer_name,o.product_name from Customers c left join Orders o on c.customer_id = o.customer_id
group by c.customer_id ,c.customer_name,o.product_name
having sum(if(o.product_name = 'A',1,0)) > 0 and sum(if(o.product_name = 'B',1,0)) > 0 and sum(if(o.product_name = 'C',1,0)) = 0
其实这一句SQL执行(select c.customer_id,c.customer_name,o.product_name from Customers c left join Orders o on c.customer_id = o.customer_id
group by c.customer_id ,c.customer_name,o.product_name),得到的结果是:
如果再加上 having sum(if(o.product_name = 'A',1,0)) > 0 and sum(if(o.product_name = 'B',1,0)) > 0 and sum(if(o.product_name = 'C',1,0)) = 0
结果是空的。
因为它是对每一行的记录,去叠加执行这些条件(等于A,等于B,不等于C),比较的。
很显然不可能有一行记录,同时满足等于A,等于B,不等于C。
除非,把product_name 这列 隐藏。根据customer_id 和customer_name去分组,这样他们的product_name 就会被聚合起来,虽然我们看不见 product_name ,但是我们却可以对它进行统计。好神奇~!
参考答案:
select c.customer_id,c.customer_name from Customers c left join Orders o on c.customer_id = o.customer_id
group by c.customer_id ,c.customer_name
having sum(if(o.product_name = 'A',1,0)) > 0 and sum(if(o.product_name = 'B',1,0)) > 0 and sum(if(o.product_name = 'C',1,0)) = 0