Mysql查询进阶

Posted 自由乐土

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql查询进阶相关的知识,希望对你有一定的参考价值。

mysql查询(进阶)

一.聚合函数查询

(where后面不能出现聚合函数,一定记住)

准备数据


– 创建数据库exam;
create database if not exists exam;
– 创建表exam_result;
create table if not exists exam_result(
id int,
name varchar(10),
math decimal(4,1),
Chinese decimal(4,1),
English decimal(4,1)
);
– 插入数据
insert into exam_result(id,name,Chinese,math,English) values
(1,‘唐三藏’,67,98,56),(2,‘孙悟空’,87.5,78,77),(3,‘猪悟能’,88,98,90),
(4,‘曹孟德’,82,84,67),(5,‘刘玄德’,55.5,85,45),
(6,‘孙权’,70,73,78.5),(7,‘宋公明’,75,65,30);
执行画面:
在这里插入图片描述
常见的统计总数、计算平均数等操作,可以使用聚合函数来实现,
常见的聚合函数有:

在这里插入图片描述

COUNT的用法

测试:
– 统计班级有多少人:
select count() from exam_result;
select count(1) from exam_result;
select count(3) from exam_result;
执行画面:
在这里插入图片描述
count后面括号内数字无意义,可以写成
或数字,但结果还是查询总人数。
也可以和去重一起使用
已知唐三藏数学和猪悟能的数学一样,而要查询数学成绩不一样的人有几种,则可这样查询:
在这里插入图片描述

sum的用法:

在这里插入图片描述

avg的用法

在这里插入图片描述

max的用法

在这里插入图片描述

min的用法

在这里插入图片描述

二.GROUP BY 子句

(一定记住,where不能出现在group by语句后面,但是可以在group by的前面)
select中使用group by子句可以对指定列进行分组查询。
需要满足:使用group by 进行分组查询时,select指定的字段必须是“分组依据字段”,其他字段若想出现在select中则必须包含在聚合函数中。
语法:
select column1,sum(column2),… from table group by column1,column3;
准备数据:
在这里插入图片描述
要查询每个角色的最高工资、最低工资和平均工资
在这里插入图片描述

HAVING作为条件筛选

group by子句进行分组以后,需要对分组结果再进行条件过滤时,不能用where语句,需要用到having与聚合函数组合起来进行条件筛选
例如
要显示工资低于1500的角色和它的平均工资
在这里插入图片描述

三.联合查询

问题:什么是联合查询?为什么要联合查询?
联合查询就是两张表或者两张以上的表,进行 连接查询。
为什么要联合查询:就是因为,我们所需要的数据,不 仅仅是来自于一张表的,他是来自于多张表的。所以,我们要进行联合查询。
前提知识:笛卡尔积
问题:什么是笛卡尔积?
笛卡尔乘积是指在数学中,两个集合X和Y的笛卡尔积(Cartesian product),又称直积,表示为X × Y,第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员
通俗点:笛卡尔积就是排列组合的结果。
举个例子:
集合A = {1 , 2 ,3},集合·B = {a , b},则集合A和集合B的笛卡尔积是:
(1,a)、(1, b)、(2, a)、(2,b)、(3,a)、(3,b)。
而联合查询是对多张表的数据取笛卡尔积。当然在取数据的时候,一定是要满足某种规则的。这几种规则就是接下来要说的几种
准备数据:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
每个表的内容:
在这里插入图片描述
在这里插入图片描述

内连接(查询出两张或多张表之间的交集)

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

案例:
1.要查询许仙同学的成绩
– 1.分析可以看出要查询的信息来自两张表,即:学生表和成绩表则要进行联合查询。
– 2.联合查询即是:select * from score inner join student;但是要选取有用的信息,需要让 student.id = score.student_id才是有用信息。
– 3.观察可以看出许仙同学的id是4,而有用信息中student_id = 4的那几组成绩信息才是许仙同学的。
所以最终结果应该是:
select * from student inner join score on student.id = score.student_id and student.id = 4;
在这里插入图片描述
但是可以发现此时查的成绩不知道是哪门课的,而且好多我们不需要的信息也显示出来了,可以改进一下:
select stu.id,stu.sn,stu.name,sco.score,stu.classes_id from student stu
inner join score sco on stu.id = sco.student_id and stu.id = 4
inner join course cou on sco.course_id = cou.id;

在这里插入图片描述
或者用where写法:
select stu.id,stu.sn,stu.name,sco.score,stu.classes_id
from student stu,score sco,course cou
where stu.id = sco.student_id and stu.id = 4 and sco.course_id = cou.id;
在这里插入图片描述
结果一样的。
2.查询所有同学的总成绩和个人信息
写法为:
select stu.id,stu.name,stu.sn,stu.classes_id,sum(sco.score)
from student stu,score sco
where stu.id = sco.student_id
group by stu.id;

在这里插入图片描述
我们发现有老外学中文同学的成绩没显示出来,那么怎么解决呢?
答案就是用下面的外连接解决。

外连接

外连接分为左外连接和右外连接。如果联合查询,左侧的表完全显示我们就说是左外连接;右侧的表完全显示我们就说是右外连接。
– 查询所有同学的总成绩和个人信息,成绩为null的也要显示出来
此处用左外连接是:
select stu.id,stu.name,stu.sn,stu.classes_id,sum(sco.score)
from student stu left join score sco
on stu.id = sco.student_id
group by stu.id;

在这里插入图片描述

右外连接是:
– 右外连接
select stu.id,stu.name,stu.sn,stu.classes_id,sum(sco.score)
from score sco right join student stu
on stu.id = sco.student_id
group by stu.id;

在这里插入图片描述

自连接

自连接是指在同一张表连接自身进行查询,即把一张表当成两张表使用。
所以可以尝试给两张表起两个不同别名。
案例:
– 显示所有“计算机原理”成绩比“java”成绩高的成绩信息
select s1.
from score s1,score s2
where s1.student_id = s2.student_id and s1.course_id = 1 and s2.course_id = 3
and s1.score < s2.score;
*
在这里插入图片描述

或者
select s1. from score s1 inner join score s2
on s1.student_id = s2.student_id and s1.course_id = 1 and s2.course_id = 3
and s1.score < s2.score;
*
在这里插入图片描述

子查询

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

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

案例:查询与“不想毕业”同学的同班同学
select * from student where classes_id =
(select classes_id from student where name = ‘不想毕业’);

在这里插入图片描述

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

案例:查询“语文“或”英文“课程的成绩信息

1.使用 IN 关键字
select * from score where course_id in (select id from course where name = ‘语文’ or name = ‘英文’);
或者
select * from score where course_id not in (select id from course where name != ‘语文’ and name != ‘英文’);

在这里插入图片描述
可以使用多列包含
– 插入重复的分数:score,student_id,course_id重复
insert into score (score,student_id,course_id) values (70.5,1,1),(98.5,1,3),(60,2,1);
– 查询重复的分数
select * from score where (score,student_id,course_id) in
(select score,student_id,course_id from score group by score,student_id,course_id
having count(
) > 1);*
在这里插入图片描述

2.使用 exists 关键字

查询“语文“或”英文“课程的成绩信息
select * from score sco where exists (select sco.id from course cou where (name = ‘语文’ or
name = ‘英文’) and cou.id = sco.course_id);

在这里插入图片描述
exists关键字使用提醒:
1、首先执行一次外部查询,并缓存结果集
2、遍历外部查询结果集的每一行记录R,代入子查询中作 为条件进行查询,
3、如果子查询有返回结果,则EXISTS子句返回TRUE,这 一行R可作为外部查询的结果行,否则不能作为结果

合并查询

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

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

案例:查询id小于3,或者名字为“英文”的课程。
select * from course where id < 3
union
select * from course where name = ‘英文’;

在这里插入图片描述

union all
该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行。
案例:查询id小于3,或者名字为“java”的课程。
– 可以看到结果集中出现重复数据java
select * from course where id < 3
union all
select * from course where name = ‘java’;

在这里插入图片描述

以上是关于Mysql查询进阶的主要内容,如果未能解决你的问题,请参考以下文章

MySQL进阶语句

MySQL进阶实战7,查询的执行过程

mysql进阶5:分组查询

Mysql查询相关知识(进阶一 基础查询 select,进阶二 where(条件查询))

Mysql查询相关知识(进阶五:分组查询,进阶六 连接查询)

MySQL 查询语句使用进阶