订阅更新

买下了所有产品的客户:关系除法

SQL 实战 123 题 · 第 47 题 中等 约 2 分钟读完

LeetCode 1045 · 关系除法、COUNT DISTINCT 与总数比较

本文目录
  1. 面试怎么回答
  2. 题意
  3. 表结构
  4. 思路
  5. 参考解法
  6. 易错点

面试怎么回答

这是关系除法。我按客户分组,HAVING COUNT(DISTINCT product_key) = (SELECT COUNT(*) FROM Product)。要提一句前提:购买记录里的产品都在产品表里;否则要先 JOIN 产品表过滤,再做计数比较。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

题意

客户购买表记录客户买过的产品,产品表是全部产品清单。找出买过产品表中所有产品的客户 ID。

表结构

  • Customer:customer_id、product_key(可能重复)
  • Product:product_key(主键)

思路

「买全了所有产品」在关系代数里叫除法。最实用的写法是计数比较:每个客户买过的不同产品数,等于产品总数,就说明全买了。前提是客户买的产品都在产品表里(题目保证了外键关系)。

参考解法

select customer_id
from Customer
group by customer_id
having count(distinct product_key)=(
select count(*) cnt
from Product)

易错点

  • 用 COUNT(*) 而不是 COUNT(DISTINCT product_key),重复购买会让计数虚高。
  • 如果购买记录里可能有产品表之外的产品,要先关联产品表再计数,否则可能「数量对上但不是同一批产品」。
刷题进度保存在当前浏览器