3.分组查询
分组数据:group by
一般跟聚集函数一起使用
分组数据中普通字段不可以跟聚集函数一起使用。
只有出现在group by后的字段,才能在select的后面使用
sql语句中先where筛选 再group by分组
例:查询每个班的最高分
先查询一共有哪几个班: select distinct sclass from t_student;
分组后的查询,会返回很多结果,即 从所有分组中的每个组来查询
select sclass, max(sscore) from t_student group by sclass;
例: 查询每个班的最大年龄,及姓名
select max(sage),sclass from t_student group by sclass;
select ssex from t_student group by ssex;
例: 按照系编号分组,求每个组有多少人
select did,count(*) from t_student group by did;
按照系编号和班级分组,查询每个组有多少男生
select did,sclass,count(*) from t_student where ssex='男' group by did,sclass ;
例:统计每个班有多少女生分数是500分以上
select sclass,count(*) from t_student where ssex='女'and sscore > 500
group by sclass;
例:在学生信息表中将1990年以后出生的学生且有系编号有班级编号的学生按照系编号、
班级编号分组,
统计出每个组的人数。输出每个组的系编号、
班级编号和人数并按照人数升序排列取前3个结果。
select did,sclass,count(*) as a from t_student
where sbir >'1990-01-01' and not did is null and not sclass is null
group by did,sclass order by a limit 3;
group by did,sclass
group by sclass,did
order by did,sclass
order by sclass,did
分组后的筛选:使用关键字having。having的语法与where 一样。
按照班级编号分组,查询每个组的女生的平均分,输出平均分为500分以上的组
select sclass,avg(sscore) as a from t_student
where ssex='女' group by sclass having a > 500;
分组查询后统计(横向统计):
在学生信息表中将分数是450分以上的学生按照班级和年龄分组,输出每个组的人数,并用ROLLUP统计。
select count(*) from t_student where sscore > 450 group by sclass,sage with rollup;
在学生信息表中将19岁以上且分数是460分以上的学生按照系编号分组,并用ROLLUP统计。
select count(*) from t_student where sscore > 460 group by did with rollup;
select 顺序:
select distinct*** from ***** where **** group by **** having**** order by *** limit ****;
在学生信息表中将系编号和班级编号不为空的学生按照班级分组,
统计每个组有多少个不同的年龄(即去掉年龄的重复)并取别名“不同年龄”,
输出每个组的班级编号和不同年龄的个数,并按照年龄个数升序排列,
取前两个结果。
select sclass,count(distinct sage) as '不同年龄' from t_student
where not did is null and not sclass is null
group by sclass order by 不同年龄 limit 2;
在学生信息表中将1班和3班的学生且年龄是18岁以上的学生按照系编号分组,
如果系编号为空则改为0。统计每个组的人数个数、最大年龄、最高分数(分别取别名),
输出结果中人数大于1的组的信息,并按照系编号降序排列取第一个结果。
select ifnull(did,0),count(*) as a,max(sage) as b,max(sscore) as c
from t_student where (sclass = 1 or sclass = 3) and sage > 18
group by did having a > 1 order by did desc limit 1;
在学生信息表中使用like找出英文名含有字母“e”和“a”的
且这两个字母都不在名字的首尾 的学生的姓名和英文名
select * from t_student where sename like '_%e%a_' or sename like '_%a%e_'
select * from t_student where sename regexp '^[^ea].*e.*a.*[^ea]$'
用正则表达式在学生信息表中找出英文名字不含有l-p之间字母的学生的姓名和英文名字,
并按照分数的降序排列。
select * from t_student where sename regexp '^[^l-p]{1,}$';
select * from t_student where not sename regexp '[a-z]';