统计并筛选分组
查找达到阈值的分组,掌握“订单数超过 N 的客户”这一经典问题
统计并筛选分组 是 CoddyKit 上的免费 Coding Interview Prep 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Coding Interview Prep 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Coding Interview Prep 课程共包含 4 节课。
最常见的分组问题
'找出订单数超过 N 的客户'是 GROUP BY 面试题中的经典问题。类似问题层出不穷:销售次数超过 X 的产品、至少有 Y 名员工的部门、登录次数超过 Z 的日期。
它们遵循的模式完全相同:分组、计数,然后使用 HAVING 筛选分组。
第一步:统计每个分组
首先统计每个分组中的行数。按定义'客户'或'产品'的键分组,然后应用 COUNT(*)。
这样会为每个分组生成一行,并显示其大小。此时还没有进行筛选,只是在测量每个分组。
SELECT customer_id, COUNT(*) AS order_count
FROM orders
GROUP BY customer_id;第二步:使用 HAVING 筛选
现在只保留达到阈值的分组。该条件作用于聚合值,因此必须放在 HAVING 中,而不是 WHERE 中。
可以将其理解为:'按客户对订单分组,然后只保留订单数超过五的客户。'这就是经典问题的完整答案。
SELECT customer_id, COUNT(*) AS order_count
FROM orders
GROUP BY customer_id
HAVING COUNT(*) > 5;COUNT DISTINCT 与 COUNT 全部行
请注意题目措辞。'订购了超过 3 种不同产品的客户'需要使用 COUNT(DISTINCT product_id),而不是 COUNT(*)。
COUNT(*)统计分组中的行数。COUNT(DISTINCT col)统计不重复的非 NULL 值。
面试官会在题目中加入'不同'或'唯一'等词,以测试您是否会使用 DISTINCT。
SELECT customer_id, COUNT(DISTINCT product_id) AS distinct_products
FROM orders
GROUP BY customer_id
HAVING COUNT(DISTINCT product_id) > 3;使用 SUM 而不是 COUNT 进行筛选
同样的结构也适用于求和。'消费总额超过 1000 的客户'需要按客户分组,并根据 SUM(amount) 进行筛选。
任何聚合值都可以作为 HAVING 条件的依据:COUNT、SUM、AVG、MAX、MIN。理解题目要求统计的指标,就能判断应筛选哪个聚合值。
SELECT customer_id, SUM(amount) AS total_spent
FROM orders
GROUP BY customer_id
HAVING SUM(amount) > 1000;多个分组条件
HAVING 可以使用 AND/OR 组合条件,包括针对不同聚合值的条件。'订单数超过 5 且平均订单金额超过 100 的客户'可以写在同一个 HAVING 子句中。
每个条件都引用自己的聚合值;所有条件都会在分组之后计算。这表明您能够清晰地表达复合业务规则。
SELECT customer_id,
COUNT(*) AS orders,
AVG(amount) AS avg_order
FROM orders
GROUP BY customer_id
HAVING COUNT(*) > 5 AND AVG(amount) > 100;组合使用 WHERE 和 HAVING
很多时候,您必须先筛选行,再进行计数。'在今年的订单中,找出订单数超过 5 的客户'需要使用 WHERE 筛选日期,并使用 HAVING 筛选计数结果。
WHERE 先缩小行的范围,然后再进行分组并应用 HAVING 阈值。在一个查询中正确使用这两个子句,是达到中级水平的体现。
SELECT customer_id, COUNT(*) AS orders_this_year
FROM orders
WHERE order_date >= '2024-01-01'
GROUP BY customer_id
HAVING COUNT(*) > 5;查找重复项
还有一个密切相关的问题:'查找重复的电子邮件地址。'请按本应唯一的列分组,并只保留计数大于一的分组。
这个简单模式可以检测重复键、重复交易,或任何出现次数超过预期的值。面试官会通过它测试您是否将分组视为一种去重工具。
SELECT email, COUNT(*) AS times_seen
FROM users
GROUP BY email
HAVING COUNT(*) > 1;计数恰好相等的分组
阈值并不总是“大于”。“订单数恰好为一个”的客户使用 HAVING COUNT(*) = 1;“至少 3 个”使用 >= 3。
请留意题目中的边界词:“超过”“至少”“恰好”“少于”。每个词组都对应不同的比较运算符,面试官会考查您是否准确理解了这一点。
-- One-time customers
SELECT customer_id, COUNT(*) AS orders
FROM orders
GROUP BY customer_id
HAVING COUNT(*) = 1;只返回键
有时题目只需要符合条件的标识符,而不是计数值,通常是为了供另一个查询使用。您仍然需要分组和筛选,但 SELECT 只选择键。
随后,您可以将其包装在 IN 子查询中,或使用连接来提取这些客户的完整记录。了解这种组合方式是资深水平的体现。
SELECT customer_id
FROM orders
GROUP BY customer_id
HAVING COUNT(*) > 5;面试解题指南
对于任何“满足阈值的分组”问题,请大声依次说明四个步骤:(1)确定分组键,(2)选择聚合度量,(3)根据题目措辞决定比较运算符,(4)将行筛选条件放入 WHERE,将聚合筛选条件放入 HAVING。
这个模板可以解决整类计数与筛选问题。
快速检查
请选择符合题意的查询。
回顾
模式:按键分组,进行聚合,再使用 HAVING 筛选分组。这个模式可以解决“订单数超过 N 个”、高消费客户、重复项以及只有一次订单的客户等问题。
- 使用
COUNT(*)统计行数,使用COUNT(DISTINCT col)统计不重复的值。 - 让比较运算符与题目措辞相匹配。
- 行筛选条件放入 WHERE,聚合筛选条件放入 HAVING。
- 只 SELECT 键,以便供 IN 子查询或连接使用。
常见问题解答
「统计并筛选分组」课时是免费的吗?
是的 — 「统计并筛选分组」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Coding Interview Prep 课程的其余内容,请升级到 CoddyKit PRO。 Coding Interview Prep 课程共包含 4 节课。
「统计并筛选分组」这节课中我会学到什么?
查找达到阈值的分组,掌握“订单数超过 N 的客户”这一经典问题 你通过在浏览器中直接运行的动手代码来练习 Coding Interview Prep,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Coding Interview Prep 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Coding Interview Prep 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「统计并筛选分组」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Coding Interview Prep 课中编写并运行代码吗?
能。每节 Coding Interview Prep 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。