分组查询
在 SELECT 语句中,允许使用 GROUP BY 子句将查询结果按照一个或多个字段进行分组,字段值相同 的为一组,对每个组进行聚合计算,实现数据的分组汇总
select <字段名列表> from <表名> [where <查询条件>] group by <字段名列表>;
select 后的字段名应该是分组字段和聚合字段以及一一对应的字段。
group by分组字段可以是一个或多个。
如果分组字段中包含有null值,则null值所在的行单独分为一组。
1.组内聚合
分组后需要对每个组内的数据进行聚合运算,可以使用sum、avg、count、max、min函数对数值型数据进行聚合计算,使用max和min函数对日期时间型数据进行聚合,使用group_concat函数对字符串型 数据进行分组合并
单字段分组:查询各部门的平均工资
select deptno,avg(sal) 平均工资 from emp group by deptno;
多字段分组:查询各部门不同职位的平均工资
select deptno,job,avg(sal) 平均工资 from emp group by deptno,job;
2.分组后筛选
在SELECT 语句中,使用GROUP BY子句进行分组后,如果需要对分组后的数据进行筛选,可以使用 HANING子句指定筛选条件。
select <字段名列表> from <表名> [where <查询条件>] group by <分组字段列表> having <筛选条件>;
HAVING 子句和 WHERE 子句非常相似,都是对数据进行过滤,HAVING 子句支持 WHERE 子句中所有的操作符和语法
示例:查询各部门clerk的低工资
select deptno,job,min(sal) 最低工资 from emp where job='clerk' group by deptno;
select deptno,job,min(sal) 最低工资 from emp group by deptno,job having job='clerk';
2.1WHERE与HAVING的区别:
WHERE 子句主要用于过滤表,而 HAVING 子句主要用于过滤分组。 WHERE 子句不可以使用聚合函数,HAVING 子句中可以包含聚合函数。 HAVING 子句是在数据分组后进行过滤,WHERE 子句会在数据分组前进行过滤,WHERE 子句排 除的行不包含在分组中。
示例:查询各部门平均工资大于3000的职位
select deptno,job,avg(sal) from emp group by deptno,job having avg(sal)>3000;
2.2HAVING 子句中的筛选字段必须是可以出现在分组结果中的字段 (即分组字段,聚合字段,或者一一对应的字段)
如果想筛选某个字段,如果其无法做聚合字段,一一对应的字段,可以将其放在分组里。
这里的“可以出现在分组里",不是一定要select出来。
查询结果排序
SELECT语句查询出的数据如果不进行排序,数据一般将以它在底层表中出现的顺序显示,这可以是数据初添加到表中的顺序。但是如果数据后来进行过更新或删除,则此顺序将会受到MySQL重用回收存储空间的影响。关系数据库设计理论认为,如果不明确规定排序顺序,则不应该假定查询出的数据的顺序有意义。
可以使用ORDER BY子句按一个或多个字段对SELECT语句查询出的数据进行排序。
select <字段名列表> from <表名> order by <字段名列表> [排序方向];
按多个列排序时,先按照第一个字段排序,仅在多个行第一个字段值相同时才按照第二个字段进行排 序。如果第一个字段值都是唯一的,则不会按照第二个字段排序。
指定排序方向:asc升序,desc降序(没有指定排序方向时,默认是asc升序)
单字段排序:查询所有员工信息按sal降序显示
select * from emp order by sal desc;
多字段排序:查询所有员工信息按deptno升序、sal降序显示
select * from emp order by deptno,sal desc;
排序字段中的null默认排在最前面
限制查询结果数量
在使用SELECT 语句时,往往返回的是所有匹配的行,有些时候我们仅需要返回第一行或者前几行,这 时候就需要用到LIMT 子句。
select <字段名列表> from <表名> limit [偏移量,] 行数;
lmit接受一个或两个数字参数,参数必须是一个整数常量。
第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的大数目。
如果只给定一个参数,表示返回大的记录行数目。
初始记录行的偏移量是0(而不是1)。








暂无数据