分组查询
GROUP BY 是用于对查询结果进行分组的子句,通常与聚合函数(如 SUM、COUNT、AVG、MAX、MIN 等)结合使用,以便对每个分组的数据进行统计或计算。
为 GROUP BY 的列创建索引可以加速分组操作,但应避免在大表上使用复杂的多列组。
1. 基本语法
Section titled “1. 基本语法”- 数据分组:将相同值的行归为一组。
- 聚合计算:对每个分组应用聚合函数(如求和、计数、平均值等)。
SELECT 列名1, 聚合函数(列名2)FROM 表名WHERE 筛选条件GROUP BY 列名1;
GROUP BY将数据按指定列的值分组。 每个分组返回一行结果,通常结合聚合函数对分组后的数据计算。
2. HAVING 子句
Section titled “2. HAVING 子句”在 SQL 中,HAVING 子句用于对 GROUP BY 分组后的结果进行筛选。它与 WHERE 子句类似,但核心区别在于:
-
WHERE:在数据分组前过滤==原始数据==(操作对象是表中的原始行)。 -
HAVING:在数据分组后过滤==聚合结果==(操作对象是分组后的聚合值)。
WHERE 在分组之前进行过滤,不满足条件的记录不参与分组;而 HAVING 在分组之后对结果进行过滤。
SELECT 分组字段, 聚合函数(统计字段)FROM 数据表WHERE 分组前筛选条件 -- ⚠️ 不能使用聚合函数GROUP BY 分组字段HAVING 分组后筛选条件; -- ✅ 可以使用聚合函数3. 注意事项
Section titled “3. 注意事项”- 错误用法
-- 错误示例:SELECT 包含非聚合列且未在 GROUP BY 中声明SELECT name, department, AVG(salary)FROM employeesGROUP BY department;
name不在GROUP BY中,且未使用聚合函数,可能导致多值不确定性问题。所以大部分数据库会报错:“name not in GROUP BY”。 有些宽松的数据库(比如 MySQL 的ONLY_FULL_GROUP_BY关掉时)会“随便挑一个 name”,但这是非标准行为,结果不可控。
当你使用 GROUP BY 时,查询中的每一列要么需要被聚合,要么需要出现在 GROUP BY 子句中。
- 正确做法
SELECT group_concat(name) as name, department, MAX(salary) AS max_salaryFROM employeesGROUP BY department;
SELECT中的非聚合列必须在GROUP BY中声明,使用聚合函数处理非分组列。
4. WITH ROLLUP
Section titled “4. WITH ROLLUP”SELECT department, job_title, SUM(salary)FROM employeesGROUP BY department, job_title WITH ROLLUP;生成分组的小计和总计(类似多维分析),结果会包含按
department的小计,以及最终的总计。