SQL JOIN、GROUP BY 与聚合查询
JOIN、GROUP BY 与聚合函数是面试和业务查询里最常一起出现的一组 SQL 能力,关键不只是会写语法,而是理解它们各自解决什么问题以及如何配合。
#type / synthesis
#status / growing
#tech / dev / backend
#resource / sql
#resource / database
[!info] related notes
- 所属 MOC: 数据库 MOC
- 前置概念: SQL, 查询
- 并列概念: 数据库索引, SQL 查询执行流程, SQL HAVING 和 WHERE 的区别, SQL 子查询, SQL 分页
- 相关资源: MySQL, 中国移动浙江金华系统开发工程师(Web端)春招复试准备
SQL JOIN、GROUP BY 与聚合查询
一句话定义
JOIN 解决“多表怎么连”,GROUP BY 解决“按什么分组”,聚合函数解决“每组怎么算”,三者合起来就是很多业务统计和列表联查题的核心。
为什么它们总是被一起问
因为真实业务查询经常不是单表直接拿数据,而是:
- 先把用户表和订单表连起来
- 再按用户分组
- 最后统计每个用户有多少订单、总金额多少、最近一次下单时间是什么
所以这三件事天然经常一起出现。
先分清它们各自解决什么问题
1. JOIN
JOIN 解决的是:
多张表之间通过什么关系拼成同一条结果。
常见例子:
- 用户表和订单表通过
user_id关联 - 订单表和商品表通过
product_id关联
2. GROUP BY
GROUP BY 解决的是:
结果要按哪个维度聚成一组。
例如:
- 按用户分组
- 按日期分组
- 按部门分组
3. 聚合函数
聚合函数解决的是:
每一组里到底算什么值。
最常见的有:
COUNT(*)SUM(amount)AVG(score)MAX(created_at)MIN(created_at)
常见 JOIN 怎么理解
1. INNER JOIN
只保留两边都能匹配上的记录。
适合:
- 你只关心“确实有关联”的数据
2. LEFT JOIN
保留左表全部记录,右表匹配不上时补 NULL。
适合:
- 你要保留主表完整结果
- 即使右表没有匹配数据,也要显示出来
这也是面试里非常常见的一类题,比如:
- 查出所有用户及其订单数,包括没下过单的用户
最小例子 / 最小场景
1. 统计每个用户订单数
SELECT user_id, COUNT(*) AS order_count
FROM orders
GROUP BY user_id;
这题没有 JOIN,重点是:
- 先按
user_id分组 - 再统计每组有多少行
2. 查出所有用户及其订单数,包括没下过单的用户
SELECT u.id, u.name, COUNT(o.id) AS order_count
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
GROUP BY u.id, u.name;
这题同时用到了:
LEFT JOIN:保留所有用户GROUP BY:按用户聚合COUNT(o.id):统计每个用户匹配到的订单数
最容易错的地方
1. 把 COUNT(*) 和 COUNT(column) 混为一谈
COUNT(*)统计的是组内行数COUNT(column)统计的是该列非NULL的行数
在 LEFT JOIN 场景里,这个区别尤其重要。
2. GROUP BY 后忘了非聚合列的约束
当你用了 GROUP BY:
- 出现在
SELECT里的非聚合列,通常也要出现在GROUP BY中
否则语义会不清楚,或者直接报错。
3. 以为 JOIN 一定会更慢
JOIN 会不会慢,不只看“用了 JOIN”,还要看:
- 关联字段是否有索引
- 表有多大
- 过滤条件写在哪里
- 查询结果是否被过度放大
从面试角度最该会什么
1. 先说清业务问题,再写 SQL
比起直接背语法,面试更稳的答法是:
- 这题要不要保留主表全部数据
- 要按什么维度聚合
- 最后统计什么指标
2. 至少会这几类题
- 每个用户有多少订单
- 每个部门有多少员工
- 查出没有下单的用户
- 统计某时间范围内每天的订单数
3. 把它和性能意识连起来
写得出来只是第一步,还要知道:
- JOIN 字段常常需要索引
- GROUP BY 可能带来排序或聚合成本
- 大表联查时不能只凭感觉写
进一步延伸时常一起补什么
- 如果题目开始问“聚合前过滤还是聚合后过滤”,就接 SQL HAVING 和 WHERE 的区别。
- 如果题目变成“先查一个中间结果,再继续判断”,就接 SQL 子查询。
- 如果题目落到接口列表和大结果集返回,就接 SQL 分页。
最短记忆方式
- JOIN:表怎么连
- GROUP BY:按什么分组
- 聚合函数:每组怎么算