MySQL~聚合查询与联合查询(多表查询、复合查询)

目录

聚合查询

聚合函数

GROUP BY子句

 HAVING

联合查询 

内连接

外连接

自连接 

子查询 

单行子查询

多行子查询 

合并查询 


聚合查询

聚合函数

首先创建一个学生表,用来演示聚合函数的作用

-- 创建学生表
drop table if exists student;
create table student(
    id int primary key auto_increment,
    sname varchar(20) not null,
    math decimal(5,2),
    english decimal(5,2),
    chinese decimal(5,2)
);

 对其中插入若干列数据,插入后的student表为

常见的统计总数、计算平均值等操作,可以使用聚合函数来实现,常见的聚合函数有:

· count(某个字段):获取整个结果集的行数.

count(某个字段) = count(*) = count(常数).

例如:

-- 统计班级内有多少同学
select count(*) from student;

· sum(某个字段):将结果集,这个字段求和计算

-- 统计数学成绩总分
select sum(math) from student;

 · avg(某个字段):将结果集,这个字段求平均值计算

-- 统计平均总分
select avg(math + english + chinese) 平均总分 from student;

· max(某个字段): 将结果集,这个字段取最大值

-- 返回英语分数的最大值
select max(english) from student;

· min(某个字段):将结果集,这个字段取最小值

-- 返回英语分数大于100分的最小值
select min(english) from student where english > 100;

GROUP BY子句

select中使用group by子句可以对指定列进行分组查询.需要满足:使用group by进行分组查询时,select指定的字段必须是“分组依据字段”,其他字段若想出现在select中则必须包含在聚合函数中.

语法:

select xxx, max(xxx), ... from 表名 group by xxx;

· 首先准备测试表

-- 准备测试表
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
('张三', '游戏代练', 14256.32),
('李四', '游戏代练', 24256.32),
('ppq', '娱乐主播', 64256.32),
('高迪', '娱乐主播', 54256.32),
('王五', '游戏代练', 14256.32),
('赵某', '工作室董事长', 104256.32);

· group by子句的使用示例

查询每个职业的最高工资、最低工资和平均工资

-- 查询每个职业的最高工资、最低工资和平均工资
select role, max(salary), min(salary), avg(salary) from emp group by role;

 HAVING

group by子句进行分组后,需要对分组结果再进行条件筛选,不能使用where语句而需要用到having来对其进行筛选.

· having的使用示例

①显示平均工资低于100000的角色和它的平均工资

-- 显示平均工资低于100000的角色和它的平均工资
select role, avg(salary) from emp group by role having avg(salary) < 100000;

联合查询 

笛卡尔积

实际开发中往往数据来源于不同的表,所以需要多表联合查询,多表联合查询是对多张表的数据取笛卡尔积,例如下列所示的两张表取笛卡尔积

· 首先建立四张表,分别为:班级表、学生表、课程表、中间表(学生课程考试成绩表)

建表代码已上传至gitee中:点击查看代码

· 再分别对建好的表中进行插入数据,具体代码已上传至gitee代码仓库中,链接在上面.

· 班级表数据 

· 学生表数据

· 课程表数据

· 中间表数据(考试成绩表)

中间表插入的数据较多,8名学生,6门课程,公48条记录,这里只展示部分数据

所有的初始操作已完成,下来进行各种联合查询的演示

内连接

· 语法

select 字段 from 表1 别名1 [inner] join 表2 别名2 on 连接条件 and 其他条件;
select 字段 from 表1 别名1,表2 别名2 where 连接条件 and 其他条件;

 · 查询张三同学的成绩

-- 查询张三的成绩
select sco.score from student stu inner join exam_score sco 
           on stu.id = sco.student_id and stu.name = '张三';

· 查询所有同学总成绩和同学的个人信息

-- 查询所有同学总成绩和同学的个人信息
select
    stu.name,
    sum(sco.score)
from
    student stu
    inner join exam_score sco on stu.id = sco.student_id
group by
    sco.student_id; 

外连接

外连接分为左外连接和右外连接,如果联合查询,左侧的表完全显示我们就说是左外连接;右侧的表完全显示我们就说是右连接.

· 语法

-- 左外连接,表1完全显示
select 字段名 from 表名1 left join 表名2 on 连接条件;
-- 右外连接,表2完全显示
select 字段 from 表名1 right join 表名2 on 连接条件;

· 查询所有同学的成绩及个人信息

-- 查询所有同学的成绩及个人信息
select
    stu.id,
    stu.name,
    sco.score,
    sco.course_id,
    cou.name
from 
    student stu
    left join exam_score sco on stu.id = sco.student_id
    left join course cou on sco.course_id = cou.id
order by
    stu.id;

共48条数据,只展示部分数据 

自连接 

自连接是指在同一张表连接自身进行查询.

· 显示所有”Java“成绩比”高等数学A“成绩高的成绩信息

-- 显示所有”Java“成绩比”高等数学A“成绩高的成绩信息
select
    stu.*,
    s1.score 数据库原理,
    s2.score Java
from
    exam_score s1
    join exam_score s2 on s1.student_id = s2.student_id
    join student stu on s1.student_id = stu.id
    join course c1 on s1.course_id = c1.id
    join course c2 on s2.course_id = c2.id
    and s1.score < s2.score
    and c1.name = '数据库原理'
    and c2.name = 'Java';

子查询 

子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询

单行子查询

单行子查询返回一行记录的子查询

· 查询”孙某某“同学的同班同学

-- 查询”孙某某“同学的同班同学 
select * from student where classes_id = (select
        classes_id from student where name = '孙某某');

 

多行子查询 

多行子查询返回多行记录的子查询

· 例如查询“Java”或“高等数学A”课程的成绩信息,可以使用in关键字,也可以使用exists关键字

· [NOT] IN关键字

-- 使用IN
select * from  exam_score where course_id in (select
        id from course where name = 'Java' or name = '高等数学A');

-- 使用NOT IN
select * from exam_score where course_id not in (select 
        id from course where name != 'Java' and name != '高等数学A');

 

· NOT EXISTS关键字 

-- 使用EXISTS
select * from exam_score sco where exists(select sco.id from course cou
        where (name = 'Java' or name = '高等数学A') and cou.id = sco.course_id);

-- 使用NOT EXISTS
select * from exam_score sco where not exists(select sco.id from course cou
        where (name != 'Java' and name != '高等数学A') and cou.id = sco.course_id);

合并查询 

在实际应用中,为了合并多个select的执行结果,可以使用集合操作符 unionunion all.使用unionunion all时,前后查询的结果集中,字段需要一致.

· UNION

该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行.

· 查询id小于3,或者名字为“高等数学A”的课程

-- 使用union
select * from course where id < 3
union
select * from course where name = '高等数学A';

 

· UNION ALL

该操作符用于取得两个结果集的并集.当使用该操作符时,不会去掉结果集中的重复行.

· 查询id小于3,或者名字为“Java”的课程

-- 使用union all
-- 查询id小于3,或者名字为“Java”的课程
select * from course where id < 3
union all
select * from course where name = 'Java';

本篇博客所有代码已上传至gitee中,点击获取代码:MySQL

  • 10
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Li_yizYa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值