MySQL Ⅳ 查询进阶

本文围绕SQL展开,介绍了聚合函数如count、sum等的用法,以及分组和过滤条件。还详细阐述了联合查询,包括内连接、外连接、自连接、子查询和合并查询等方式,并给出示例。最后提醒禁止三张表以上的连表查询,需在后端代码解决。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

聚合函数

exam_result表为例

drop table if exists exam_result;
create table exam_result ( 
	id INT, 
	name VARCHAR(20), 
	chinese DECIMAL(3,1), 
	math DECIMAL(3,1), 
	english DECIMAL(3,1) 
);
insert into exam_result (id,name, chinese, math, english)
values
(1,'A', 67, 98, 56), 
(2,'B', 87.5, 78, 77),
(3,'C', 88, 98, 90), 
(4,'D', 82, 84, 67), 
(5,'E', 55.5, 85, 45), 
(6,'F', 70, 73, 78.5), 
(7,'G', 75, 65, 30),
(8,'H', 78, 32, 98);

在这里插入图片描述

count

数量

select count(*) from exam_result;

在这里插入图片描述

sum

总和(不是数字,无意义)

select sum(math) from exam_result;

在这里插入图片描述

avg

平均值

select avg(math) from exam_result;

在这里插入图片描述

max

最大值

select max(math) from exam_result;

在这里插入图片描述

min

最小值

select min(math) from exam_result;

在这里插入图片描述

group by

分组

emp表为例

drop table if exists emp; 
create table emp( 
	id int primary key auto_increment, 
	name varchar(20) not null, 
	role varchar(20) not null, 
	salary numeric(11,2) 
);
insert into emp(name, role, salary) values 
('老师A','讲师', 2000.20),
('老师B','讲师', 2000.99), 
('老师C','讲师', 2000.11), 
('老师D','教授', 3000.5), 
('老师E','辅导员', 1000.33), 
('老师F','教授', 3000.66),
('老师E','辅导员', 1000.33);

查询每个角色的最高工资、最低工资和平均工资

将role 相同的分为一组,求其最大,最小,平均值

select role,max(salary),min(salary),avg(salary) from emp group by role;

在这里插入图片描述

having

过滤条件

where后不能加聚合函数,需要使用having

查询平均工资低于1500的角色和它的平均工资

select role,avg(salary) from emp group by role having avg(salary)<1500;

在这里插入图片描述

联合查询

联合查询就是两张表或者两张以上的表,进行连接查询

因为我们所需要的数据,不仅仅是来自于一张表的,而是来自于多张表的

笛卡尔积

所有的联合查询都是从笛卡尔积当中去取出数据,在取数据的时候,一定是要满足某种规则,接下来,我们来学习一下各种联合查询的方式把~

以下列表为例

drop table if exists classes; 
create table classes( 
	id int primary key auto_increment,
	name varchar(50), 
	`desc` varchar(50)
);
insert into classes(name, `desc`) values 
('计算机系2018级1班', '学习了计算机原理'),
('中文系2018级3班','学习了中国传统文学'), 
('自动化2018级5班','学习了机械自动化');

在这里插入图片描述

drop table if exists student; 
create table student( 
	id int primary key auto_increment, 
	sn int,
	name varchar(30), 
	qq_mail varchar(30), 
	classes_id int 
);
insert into student(sn, name, qq_mail, classes_id) values 
('10010','张三','123@qq.com',1), 
('10012','李四',null,1), 
('10034','王五',null,1), 
('10023','赵六','456@qq.com',1), 
('20019','郑一',null,1),
('20021','刘二','789@qq.com',2), 
('30098','lily',null,2), 
('30045','joey','happy@qq.com',2);

在这里插入图片描述

drop table if exists course; 
create table course( 
	id int primary key auto_increment, 
	name varchar(20) 
);
insert into course(name) values 
('Java'),('中国传统文化'),('计算机原理'),('语文'),('数学'),('英语');

在这里插入图片描述

drop table if exists score; 
create table score( 
	id int primary key auto_increment, 
	score DECIMAL, 
	student_id int, 
	course_id int 
);
insert into score(score, student_id, course_id) values 
(70.5, 1, 1),(98.5, 1, 3),(33, 1, 5),(98, 1, 6),
(60, 2, 1),(59.5, 2, 5), 
(33, 3, 1),(68, 3, 3),(99, 3, 5),
(67, 4, 1),(23, 4, 3),(56, 4, 5),(72, 4, 6), 
(81, 5, 1),(37, 5, 5),
(56, 6, 2),(43, 6, 4),(79, 6, 6),
(80, 7, 2),(92, 7, 6);

在这里插入图片描述
学生有8个
分数有20个
一共8*20=160个

内连接

在这里插入图片描述

select 字段 from1 别名1 inner join2 别名2 on 连接条件 and 其他条件
select 字段 from1 别名1,2 别名2 where 连接条件 and 其他条件
  1. 查询赵六同学的成绩
select stu.sn,stu.name,sco.score,cou.name as 课程名 
from student stu 
inner join score sco 
on stu.id = sco.student_id 
	inner join course cou 
	on sco.course_id = cou.id 
and stu.name='赵六';

在这里插入图片描述
注:inner可以省略
可以直接用,+where的方式写

select stu.sn,stu.name,sco.score,cou.name as 课程名
from student stu ,score sco,course cou
where stu.id = sco.student_id
and sco.course_id = cou.id
and stu.name='赵六';
  1. 查询所有同学的总成绩
select stu.sn,stu.name,sum(score)
from student stu,score sco
where stu.id = sco.student_id
group by stu.id;

在这里插入图片描述

外连接

在这里插入图片描述
查询每个同学的成绩,个人信息,若无成绩也要显示

select stu.id,stu.name,sco.score 
from student stu,score sco 
where stu.id=sco.student_id 
group by stu.id;
select stu.id,stu.name,sco.score 
from student stu left join score sco 
on stu.id=sco.student_id 
group by stu.id;
select stu.id,stu.name,sco.score 
from score sco right join student stu 
on stu.id=sco.student_id 
group by stu.id;

在这里插入图片描述

自连接

把一张表看做两张表来使用

查询所有“计算机原理”成绩比“java”成绩高的信息

select s2.* from score s1,score s2 
where s1.student_id = s2.student_id
and s1.score<s2.score
and s1.course_id = 1
and s2.course_id = 3;

在这里插入图片描述

子查询

单行子查询

返回一行记录的子查询

查询“郑一”同学的同班同学

①先查询他是哪个班的

select classes_id from student stu where name = '郑一';

在这里插入图片描述
②再查这个班有谁

select * from student where classes_id = 1;

在这里插入图片描述
③合并

select * from student 
where classes_id = (
	select classes_id 
	from student stu 
	where stu.name = '郑一'
);

多行子查询

返回多行记录的子查询

(not) in

查询语文或英语的成绩信息
①先查语文或英语的id

select id from course 
where name = '语文' or name = '英语';

在这里插入图片描述

②再查这两个id对应的成绩

select * from score 
where course_id in (
	select id from course 
	where name = '语文' or name = '英语'
);

在这里插入图片描述

(not) exists

只要这个表达式为真,返回true

select * from A where exists (
	select 1 from B 
	where B.id=A.id
);

①首先执行一次外部查询,并缓存结果集,如 select * from A
②遍历外部查询结果集的每一行记录为R,代入子查询中作为条件进行查询,如 select 1 from B where B.id=A.id
③若子查询有返回结果,exists子句返回true,这一行R可以作为外部查询结果行,否则不可

合并查询(union)

union :合并且去重

select * from student
where id <= 3
union  
	select * from student
	where name = '张三';

在这里插入图片描述

union all :合并(不去重)

select * from student
where id <= 3
union all 
	select * from student
	where name = '张三';

在这里插入图片描述

注意

禁止三张表以上的连表查询,若需要三张表,在后端代码中解决,不要在MySQL中解决

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值