语法:
insert into 要插入的表 [(列1, ..., 列n)] select {* | (列1, ..., 列n)}from 要查询的表
上述语句可以将要查询的表的某些列插入到新的表中对应的某些列
示例1: 将 student1 表(只包含 id 和 name 字段,且该表已经插入内容)的内容全部插入到 student2 表(只包含 id 和name 字段,该表尚未插入内容)中
示例2: 将 student1 表(只包含 id 和 name 字段,且该表已经插入内容)的字段 name 插入到 student2 表(只包含 id 和name 字段,该表尚未插入内容)中
聚合查询可以使用以下常用聚合函数,这些聚合函数就相当于 SQL 提供的“库函数”
函数 | 说明 |
---|---|
count([distinct] expr) | 返回查询到的数据的数量,即行数 |
sum([distinct] expr) | 返回查询到的数据的总和,不是数字就没有意义 |
avg([distinct] expr) | 返回查询到的数据的平均值,不是数字就没有意义 |
max([distinct] expr) | 返回查询到的数据的最大值,不是数字就没有意义 |
min([distinct] expr) | 返回查询到的数据的最小值,不是数字就没有意义 |
补充:
接下来以表名为 exam_result,具体数据如下的表,进行示例展示
id | name | chinese | math | english |
---|---|---|---|---|
1 | 唐三藏 | 67.0 | 98.0 | 56.0 |
2 | 孙悟空 | 87.5 | 78.0 | 77.0 |
3 | 猪悟能 | 88.0 | 98.5 | 90.0 |
4 | 曹孟德 | 82.0 | 84.0 | 67.0 |
5 | 刘玄德 | 55.5 | 85.0 | 45.0 |
6 | 孙权 | 70.0 | 73.0 | 78.5 |
7 | 宋公明 | null | null | null |
示例1: 返回查询到的数据的行数
示例2: 返回查询到的列为 chinese 数据的行数
示例3: 返回查询到的语文成绩的总和
示例4: 返回查询到的各科成绩的平均值
示例5: 返回总成绩的最高值
示例6: 返回总成绩的最低值
使用前面的聚合函数,实际上是把该表中的所有行结合起来。但还可以使用 group by 来进行分组聚合(在 group by 后面加上指定列名,那么该列中值相同的就将分成一组)
接下来我们将对表名为 emp,数据如下的表进行示例展示
id | name | role | salary |
---|---|---|---|
1 | 张三 | 开发 | 10000 |
2 | 李四 | 开发 | 11000 |
3 | 王五 | 测试 | 9000 |
4 | 赵六 | 测试 | 12000 |
5 | 田七 | 销售 | 7000 |
6 | 魔王 | 老板 | 50000 |
示例1: 查看各个岗位的平均薪资
示例2: 查看各个岗位的平均、最高、最低薪资
如果使用 group by 子句进行分组以后,需要对分组结果再进行条件过滤,这时就不能使用 where 语句了,而是使用 having 语句
注意:
示例1: 查询薪资大于10000的岗位
示例2: 排除张三薪资后,薪资大于10000的岗位
笛卡尔积思想:
学生表 A
学号 | 姓名 | 班级id |
---|---|---|
1 | 张三 | 2001 |
2 | 李四 | 2001 |
3 | 王五 | 2002 |
班级表 B
班级id | 班级名 |
---|---|
2001 | 高二(1)班 |
2002 | 高二(2)班 |
新表 C
学号 | 姓名 | 班级id | 班级id | 班级名 |
---|---|---|---|---|
1 | 张三 | 2001 | 2001 | 高二(1)班 |
1 | 张三 | 2001 | 2002 | 高二(2)班 |
2 | 李四 | 2001 | 2001 | 高二(1)班 |
2 | 李四 | 2001 | 2002 | 高二(2)班 |
3 | 王五 | 2002 | 2001 | 高二(1)班 |
3 | 王五 | 2002 | 2002 | 高二(2)班 |
补充:
通过新得到的 C 表,我们就可以将 A、B 两张表联系起来,而联系的纽带在上面的示例中就是班级id。到此时,虽然将两个表联系起来了,但是不是新表中的每条数据都是合理的,例如第2行的信息其实就是不正确的。因此将两表联系起来后,还需要加上一些条件的限制,如 A 和 B 表的班级id应该相同,此时就可以得到一个数据更合理的表 D
新表 D
学号 | 姓名 | 班级id | 班级id | 班级名 |
---|---|---|---|---|
1 | 张三 | 2001 | 2001 | 高二(1)班 |
2 | 李四 | 2001 | 2001 | 高二(1)班 |
3 | 王五 | 2002 | 2001 | 高二(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);
语法:
-- 方法一:
select 展示的列名 from 表1 [表1别名],表2 [表2别名] where 连接条件;
-- 方式二:使用 [inner] join on
select 展示的列名 from 表1 [表1别名] [inner] join 表2 [表2别名] on 连接条件;
补充:
示例1: 查询许仙同学每门课的成绩
示例2: 查询每个同学的总成绩
示例3: 查询每个同学每门课的成绩
外连接其实和内连接差不多,都是使用了笛卡尔积。内连接是针对的两个表中的每一条数据都是一一对应的,那怎么就不是一一对应了呢?例如下面两个表 A、B
A 表
id | name |
---|---|
1 | 张三 |
2 | 李四 |
3 | 王五 |
B 表
student_id | score |
---|---|
1 | 90 |
2 | 80 |
4 | 70 |
我们发现经过笛卡尔积后建立的新表时,A 表的 id 为3的记录和 B 表中没有对应的数据,B 表中 student_id 为4的记录和 A 表中也没有对应的数据,因此这两个表就不能使用内连接的方式去查询,要使用外连接
如果使用左连接的方式,新表 C 为
id | name | student_id | score |
---|---|---|---|
1 | 张三 | 1 | 90 |
2 | 李四 | 2 | 80 |
3 | 王五 | null | null |
如果使用右连接的方式,新表 D 为
id | name | student_id | score |
---|---|---|---|
1 | 张三 | 1 | 90 |
2 | 李四 | 2 | 80 |
null | null | 4 | 70 |
补充:
语法:
-- 左连接,表1完全显示
select 展示的列名 from 表1 [表1别名] [left] join 表2 [表2别名] on 连接条件;
-- 右连接,表2完全显示
select 展示的列名 from 表1 [表1别名] [right] join 表2 [表2别名] on 连接条件;
为什么自连接可以将行转换成列来进行操作呢?假设有一张表 A
student_id | course_id | score |
---|---|---|
1 | 1 | 70 |
1 | 2 | 90 |
1 | 3 | 80 |
如果我想找到原表中 student_id 为1,且其课程2成绩高于课程3的同学的信息时,就是要对行与行之间进行比较,但是一张表是不能进行该操作的
通过对自己进行笛卡尔积之后,得到新的表 B
student_id | course_id | score | student_id | course_id | score |
---|---|---|---|---|---|
1 | 1 | 70 | 1 | 1 | 70 |
1 | 2 | 90 | 1 | 2 | 90 |
1 | 3 | 80 | 1 | 3 | 80 |
此时我们发现,如果将原表进行笛卡尔积后,有了两张一样的表,就可以实施行与行之间操作
示例: 查询 Java 成绩高于计算机原理成绩的同学
分类:
补充:
示例1: 查询不想毕业同学的同班同学(首先要知道不想毕业同学的班级,然后通过班级筛选学生)
示例2: 查询语文或者英语课程的成绩信息(使用 in)
示例3: 查询语文或者英语课程的成绩信息(使用 exists)
补充:
示例: 查看 id 小于3,或者课程为 Java 的信息
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_51367845/article/details/121582910
内容来源于网络,如有侵权,请联系作者删除!