在SQL查询编写过程中,PARTITION BY和GROUP BY都是和分组相关的语法,但二者的核心逻辑和适用场景有本质区别,很多开发者在初次接触时容易混淆。GROUP BY属于标准聚合查询的一部分,作用是将数据按照指定字段进行分组,对每组数据执行聚合计算后,每组只会返回一条汇总结果,原始数据的行数会被压缩。而PARTITION BY是窗口函数的配套语法,作用是按照指定字段将数据划分为不同的分区,不会减少原始数据的行数,会在每一行数据后面附加对应分区的聚合计算结果,常用于需要同时保留明细数据和聚合结果的场景。

核心差异对比
二者的核心区别可以从多个维度进行区分,具体对比如下:
| 对比维度 | GROUP BY | PARTITION BY |
|---|---|---|
| 数据行数变化 | 分组后每组返回1条,总行数减少 | 不改变原数据行数,每行都保留 |
| 所属语法范畴 | 标准聚合查询语法 | 窗口函数配套语法 |
| 返回结果内容 | 仅返回分组字段和聚合计算结果 | 保留所有原始字段,额外增加分区聚合结果 |
| 聚合函数使用限制 | select后只能出现分组字段和聚合函数 | 聚合函数可以和普通字段同时出现在select后 |
GROUP BY的使用场景与示例
GROUP BY适合需要对数据进行分组汇总,只需要得到每组统计结果的场景,比如统计每个部门的员工人数、每个分类的商品总销量等。
基础使用示例
假设有一张员工表employee,包含dept_id(部门ID)、emp_name(员工姓名)、salary(薪资)字段,现在需要统计每个部门的员工数量,使用GROUP BY的查询如下:
-- 统计每个部门的员工数量
SELECT
dept_id,
COUNT(*) AS emp_count
FROM employee
GROUP BY dept_id;
上述查询会按照dept_id分组,每个部门返回一条记录,包含部门ID和该部门的员工总数,原始的员工明细数据不会出现在结果中。
带筛选的分组示例
如果需要统计每个部门薪资大于5000的员工数量,可以在GROUP BY后使用HAVING进行筛选:
-- 统计每个部门薪资大于5000的员工数量
SELECT
dept_id,
COUNT(*) AS high_salary_emp_count
FROM employee
WHERE salary > 5000
GROUP BY dept_id
HAVING COUNT(*) >= 2;
这里先用WHERE筛选出薪资大于5000的员工,再按部门分组,最后用HAVING筛选出员工数量大于等于2的部门。
PARTITION BY的使用场景与示例
PARTITION BY适合需要同时保留数据明细和对应分组聚合结果的场景,比如查询每个员工的薪资以及其所在部门的平均薪资,或者给每个部门内的员工薪资排序等。
基础使用示例
同样使用上面的employee表,现在需要查询每个员工的姓名、部门、薪资,以及其所在部门的平均薪资,使用PARTITION BY的查询如下:
-- 查询员工明细及所在部门的平均薪资
SELECT
emp_name,
dept_id,
salary,
AVG(salary) OVER (PARTITION BY dept_id) AS dept_avg_salary
FROM employee;
上述查询中,PARTITION BY dept_id表示按照部门ID划分分区,AVG(salary) OVER (...)表示计算每个分区的平均薪资,结果会保留所有员工的明细数据,同时每行后面都会附加该员工所在部门的平均薪资。
结合排序函数的示例
如果需要查询每个部门内员工的薪资排名,可以使用PARTITION BY结合ROW_NUMBER()排序函数:
-- 查询每个部门内员工的薪资排名
SELECT
emp_name,
dept_id,
salary,
ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS dept_salary_rank
FROM employee;
这里PARTITION BY dept_id按部门分区,ORDER BY salary DESC表示在每个分区内按薪资降序排序,ROW_NUMBER()会给每个分区内的行生成从1开始的序号,也就是每个部门内的薪资排名。
如何选择使用哪个语法
实际编写SQL时可以根据需求判断:
- 如果只需要得到分组的汇总结果,不需要保留原始明细数据,优先选择GROUP BY。
- 如果需要同时保留原始明细数据和分组的聚合/排序结果,必须选择PARTITION BY配合窗口函数使用。
- 如果需要对分组后的结果进行筛选,GROUP BY使用HAVING,而PARTITION BY的筛选需要放在外层查询中处理。
注意:PARTITION BY必须和窗口函数一起使用,不能单独出现在查询中,而GROUP BY可以单独配合聚合函数使用完成分组查询。
SQLPARTITION_BYGROUP_BY窗口函数分组聚合修改时间:2026-07-12 02:57:24