概述
平时开发时,经常会遇到一些和统计相关的 SQL 查询,需要对查询结果集进行去重,还要统计某个值或者列出现的记录数等。
我们一般使用 group by 子句或 distinct 子句来实现去重。
这里准备了一张 user 表,有 id、name、sex 和 age 四个列。模拟了 10 条数据如下:
这里做一个简单的查询实验。
group by
group by 用来对查询的结果集进行分组,分组中 group by 后面跟随的字段的值只会留下一个。
group by 子句的涉及到的字段一定要在 select 子句中出现过。
如果有统计或者计算需求,可以在 select 子句中加入函数对每个组的数据进行统计或计算。
group by 的字段需要加索引,可以大幅度提高查询的性能。
直接去重
查询不重复的用户列表:
select name from user group by name
结果如下:
分组统计
如果有其他的统计需求,选择相应的函数等,比如 count()
,max()
,min()
等等。这些函数只作用于分组的内容。
查询每个年龄的人数,结合 count()
函数:
select age, count(1) from user group by age
结果如下
可以看到 group by 还对结果集进行了排序,默认是 asc 排序。
查询每个性别的最大年龄,结合 max()
函数:
select sex, max(age) from user group by sex
结果如下
分组筛选
如果要对分组结果进行进一步筛选,需要加入 having 子句。having 子句里的字段也必须在 select 子句出现过。
查询用户数量大于 1 的年龄:
select age, count(1) as userCount from user group by age having userCount > 1
结果如下:
distinct
和 group by 的应用范围不一样,distinct 一般用来做记录条数的去重查询,而 group by 用来不重复的记录。
distinct 关注记录数量,group by 关注记录。
distinct 标记的字段加索引可以提高性能。
查询不重名的用户数量:
select count(distinct(name)) from user
结果如下: