当前位置:   article > 正文

MySQL~聚合查询与联合查询(多表查询、复合查询)_两张表联合查询使用聚合函数把重复的数据放在一块

两张表联合查询使用聚合函数把重复的数据放在一块

目录

聚合查询

聚合函数

GROUP BY子句

 HAVING

联合查询 

内连接

外连接

自连接 

子查询 

单行子查询

多行子查询 

合并查询 


聚合查询

聚合函数

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

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

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

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

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

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

例如:

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

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

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

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

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

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

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

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

  1. -- 返回英语分数大于100分的最小值
  2. 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;

· 首先准备测试表

  1. -- 准备测试表
  2. create table emp(
  3. id int primary key auto_increment,
  4. name varchar(20) not null,
  5. role varchar(20) not null,
  6. salary numeric(11,2)
  7. );

· 插入测试数据 

  1. -- 插入测试数据
  2. insert into emp(name, role, salary) values
  3. ('张三', '游戏代练', 14256.32),
  4. ('李四', '游戏代练', 24256.32),
  5. ('ppq', '娱乐主播', 64256.32),
  6. ('高迪', '娱乐主播', 54256.32),
  7. ('王五', '游戏代练', 14256.32),
  8. ('赵某', '工作室董事长', 104256.32);

· group by子句的使用示例

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

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

 HAVING

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

· having的使用示例

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

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

联合查询 

笛卡尔积

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

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

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

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

· 班级表数据 

· 学生表数据

· 课程表数据

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

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

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

内连接

· 语法

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

 · 查询张三同学的成绩

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

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

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

外连接

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

· 语法

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

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

  1. -- 查询所有同学的成绩及个人信息
  2. select
  3. stu.id,
  4. stu.name,
  5. sco.score,
  6. sco.course_id,
  7. cou.name
  8. from
  9. student stu
  10. left join exam_score sco on stu.id = sco.student_id
  11. left join course cou on sco.course_id = cou.id
  12. order by
  13. stu.id;

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

自连接 

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

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

  1. -- 显示所有”Java“成绩比”高等数学A“成绩高的成绩信息
  2. select
  3. stu.*,
  4. s1.score 数据库原理,
  5. s2.score Java
  6. from
  7. exam_score s1
  8. join exam_score s2 on s1.student_id = s2.student_id
  9. join student stu on s1.student_id = stu.id
  10. join course c1 on s1.course_id = c1.id
  11. join course c2 on s2.course_id = c2.id
  12. and s1.score < s2.score
  13. and c1.name = '数据库原理'
  14. and c2.name = 'Java';

子查询 

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

单行子查询

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

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

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

 

多行子查询 

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

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

· [NOT] IN关键字

  1. -- 使用IN
  2. select * from exam_score where course_id in (select
  3. id from course where name = 'Java' or name = '高等数学A');
  4. -- 使用NOT IN
  5. select * from exam_score where course_id not in (select
  6. id from course where name != 'Java' and name != '高等数学A');

 

· NOT EXISTS关键字 

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

合并查询 

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

· UNION

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

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

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

 

· UNION ALL

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

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

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/986596
推荐阅读
相关标签
  

闽ICP备14008679号