【MySQL 数据库】聚合查询和联合查询操作

x33g5p2x  于2021-11-27 转载在 Mysql  
字(3.9k)|赞(0)|评价(0)|浏览(696)

1. 插入被查询的结果

语法:

insert into 要插入的表 [(列1, ..., 列n)] select {* | (列1, ..., 列n)}from 要查询的表

上述语句可以将要查询的表的某些列插入到新的表中对应的某些列

示例1: 将 student1 表(只包含 id 和 name 字段,且该表已经插入内容)的内容全部插入到 student2 表(只包含 id 和name 字段,该表尚未插入内容)中

示例2: 将 student1 表(只包含 id 和 name 字段,且该表已经插入内容)的字段 name 插入到 student2 表(只包含 id 和name 字段,该表尚未插入内容)中

2. 聚合查询

2.1 介绍

2.2 聚合函数

聚合查询可以使用以下常用聚合函数,这些聚合函数就相当于 SQL 提供的“库函数”

函数说明
count([distinct] expr)返回查询到的数据的数量,即行数
sum([distinct] expr)返回查询到的数据的总和,不是数字就没有意义
avg([distinct] expr)返回查询到的数据的平均值,不是数字就没有意义
max([distinct] expr)返回查询到的数据的最大值,不是数字就没有意义
min([distinct] expr)返回查询到的数据的最小值,不是数字就没有意义

补充:

接下来以表名为 exam_result,具体数据如下的表,进行示例展示

idnamechinesemathenglish
1唐三藏67.098.056.0
2孙悟空87.578.077.0
3猪悟能88.098.590.0
4曹孟德82.084.067.0
5刘玄德55.585.045.0
6孙权70.073.078.5
7宋公明nullnullnull

示例1: 返回查询到的数据的行数

示例2: 返回查询到的列为 chinese 数据的行数

示例3: 返回查询到的语文成绩的总和

示例4: 返回查询到的各科成绩的平均值

示例5: 返回总成绩的最高值

示例6: 返回总成绩的最低值

2.3 group by 子句

使用前面的聚合函数,实际上是把该表中的所有行结合起来。但还可以使用 group by 来进行分组聚合(在 group by 后面加上指定列名,那么该列中值相同的就将分成一组)

接下来我们将对表名为 emp,数据如下的表进行示例展示

idnamerolesalary
1张三开发10000
2李四开发11000
3王五测试9000
4赵六测试12000
5田七销售7000
6魔王老板50000

示例1: 查看各个岗位的平均薪资

示例2: 查看各个岗位的平均、最高、最低薪资

2.4 having

如果使用 group by 子句进行分组以后,需要对分组结果再进行条件过滤,这时就不能使用 where 语句了,而是使用 having 语句

注意:

示例1: 查询薪资大于10000的岗位

示例2: 排除张三薪资后,薪资大于10000的岗位

3. 联合查询

3.1 介绍

笛卡尔积思想:

学生表 A

学号姓名班级id
1张三2001
2李四2001
3王五2002

班级表 B

班级id班级名
2001高二(1)班
2002高二(2)班

新表 C

学号姓名班级id班级id班级名
1张三20012001高二(1)班
1张三20012002高二(2)班
2李四20012001高二(1)班
2李四20012002高二(2)班
3王五20022001高二(1)班
3王五20022002高二(2)班

补充:

通过新得到的 C 表,我们就可以将 A、B 两张表联系起来,而联系的纽带在上面的示例中就是班级id。到此时,虽然将两个表联系起来了,但是不是新表中的每条数据都是合理的,例如第2行的信息其实就是不正确的。因此将两表联系起来后,还需要加上一些条件的限制,如 A 和 B 表的班级id应该相同,此时就可以得到一个数据更合理的表 D

新表 D

学号姓名班级id班级id班级名
1张三20012001高二(1)班
2李四20012001高二(1)班
3王五20022001高二(2)班

此时我们就可以进行一个多表查询

注意:

以下示例都是通过下面 SQL 语句建的表来进行操作学习的,如果你想在后面的内容进行操作,可以直接复制使用

drop table if exists classes;
drop table if exists student;
drop table if exists course;
drop table if exists score;

create table classes (id int primary key auto_increment, name varchar(20), `desc` varchar(100));

create table student (id int primary key auto_increment, sn varchar(20),  name varchar(20), qq_mail varchar(20) ,
        classes_id int);

create table course(id int primary key auto_increment, name varchar(20));

create table score(score decimal(3, 1), student_id int, course_id int);

insert into classes(name, `desc`) values 
('计算机系2019级1班', '学习了计算机原理、C和Java语言、数据结构和算法'),
('中文系2019级3班','学习了中国传统文学'),
('自动化2019级5班','学习了机械自动化');

insert into student(sn, name, qq_mail, classes_id) values
('09982','黑旋风李逵','xuanfeng@qq.com',1),
('00835','菩提老祖',null,1),
('00391','白素贞',null,1),
('00031','许仙','xuxian@qq.com',1),
('00054','不想毕业',null,1),
('51234','好好说话','say@qq.com',2),
('83223','tellme',null,2),
('09527','老外学中文','foreigner@qq.com',2);

insert into course(name) values
('Java'),('中国传统文化'),('计算机原理'),('语文'),('高阶数学'),('英文');

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),
-- tellme
(80, 7, 2),(92, 7, 6);

3.2 内连接

语法:

-- 方法一:
select 展示的列名 from 表1 [表1别名],表2 [表2别名] where 连接条件;

-- 方式二:使用 [inner] join on
select 展示的列名 from 表1 [表1别名] [inner] join 表2 [表2别名] on 连接条件;

补充:

示例1: 查询许仙同学每门课的成绩

示例2: 查询每个同学的总成绩

示例3: 查询每个同学每门课的成绩

3.3 外连接

外连接其实和内连接差不多,都是使用了笛卡尔积。内连接是针对的两个表中的每一条数据都是一一对应的,那怎么就不是一一对应了呢?例如下面两个表 A、B

A 表

idname
1张三
2李四
3王五

B 表

student_idscore
190
280
470

我们发现经过笛卡尔积后建立的新表时,A 表的 id 为3的记录和 B 表中没有对应的数据,B 表中 student_id 为4的记录和 A 表中也没有对应的数据,因此这两个表就不能使用内连接的方式去查询,要使用外连接

如果使用左连接的方式,新表 C 为

idnamestudent_idscore
1张三190
2李四280
3王五nullnull

如果使用右连接的方式,新表 D 为

idnamestudent_idscore
1张三190
2李四280
nullnull470

补充:

语法:

-- 左连接,表1完全显示
select 展示的列名 from 表1 [表1别名] [left] join 表2 [表2别名] on 连接条件;

-- 右连接,表2完全显示
select 展示的列名 from 表1 [表1别名] [right] join 表2 [表2别名] on 连接条件;

3.4 自连接

为什么自连接可以将行转换成列来进行操作呢?假设有一张表 A

student_idcourse_idscore
1170
1290
1380

如果我想找到原表中 student_id 为1,且其课程2成绩高于课程3的同学的信息时,就是要对行与行之间进行比较,但是一张表是不能进行该操作的

通过对自己进行笛卡尔积之后,得到新的表 B

student_idcourse_idscorestudent_idcourse_idscore
11701170
12901290
13801380

此时我们发现,如果将原表进行笛卡尔积后,有了两张一样的表,就可以实施行与行之间操作

示例: 查询 Java 成绩高于计算机原理成绩的同学

3.5 子查询

分类:

补充:

示例1: 查询不想毕业同学的同班同学(首先要知道不想毕业同学的班级,然后通过班级筛选学生)

示例2: 查询语文或者英语课程的成绩信息(使用 in)

示例3: 查询语文或者英语课程的成绩信息(使用 exists)

3.6 合并查询

补充:

示例: 查看 id 小于3,或者课程为 Java 的信息

相关文章

最新文章

更多