买了 A 和 B 却没买 C 的顾客
LeetCode 1398 · 条件聚合、「有且无」组合判断
面试怎么回答
按顾客分组,HAVING SUM(product_name = 'A') > 0 AND SUM(product_name = 'B') > 0 AND SUM(product_name = 'C') = 0,再关联顾客名、按 ID 排序。任意「买过哪些、没买过哪些」的组合,都可以用这种条件计数一次表达。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
题意
顾客表和订单表(订单记录产品名)。找出买过产品 A、也买过产品 B、但从没买过产品 C 的顾客,按顾客 ID 排序。
表结构
- Customers:customer_id(主键)、customer_name
- Orders:order_id(主键)、customer_id、product_name
思路
多个「有」和「无」的组合条件,统一用按顾客分组的条件计数表达:A 的次数 > 0,B 的次数 > 0,C 的次数 = 0。
参考解法
select o.customer_id, customer_name
from Orders o left join Customers c
on o.customer_id=c.customer_id
group by customer_id
having sum(product_name ='A')>=1 and sum(product_name='B')>=1 and sum(product_name='C')=0
易错点
- 写成
WHERE product_name IN ('A', 'B') AND product_name != 'C'是单行判断,表达不了「从没买过 C」。