【高频SQL (进阶版)】1398.购买了产品A和产品B却没有购买产品C的顾客Plus

发布于:2024-03-21 ⋅ 阅读:(78) ⋅ 点赞:(0)

思路:

思路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


网站公告

今日签到

点亮在社区的每一天
去签到