接进阶篇①,我们继续学习。

  • 一、联合查询
    • 1.1 内连接
    • 1.2 外连接
    • 1.3 内连接和左右外连接的区别
  • 二、自连接
  • 三、子查询
    • 3.1 单行子查询
    • 3.2 多行子查询
      • 使用 in 范围匹配多行
      • 另一种写法 exists
      • 两种写法的区别
    • 3.3 在 from 子句中使用子查询
  • 四、合并查询
    • union
    • union all

一、联合查询

实际开发中往往数据来自不同的表,所以需要多表联合查询。

多表查询是对多张表的数据取笛卡尔积。

我们先初始化测试数据:

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);

1.1 内连接

语法:

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

案例一: 查询 “许仙” 同学的成绩.

-- 写法一
select student.name,score.score from student,score where student.id=score.student_id and student.name='许仙';--写法二
select student.name,score.score from student inner join score on student.id=score.student_id and student.name='许仙';

运行结果:

解析:

首先,我们需要判断出会涉及到哪些表,学生表和成绩表;

其次,将两个表先进行笛卡尔积操作(会出现很多数据);

select * from student,score;

接着,给 sql 语句添加连接条件,将无意义的数据过滤掉;

select * from student,score where student.id=score.student_id;

然后,逐渐添加题目中的其它条件(学生名字),一步步缩小数据范围;

select * from student,score where student.id=score.student_id and student.name='许仙';

最后再精简查询的列,就是最后的答案。

select student.name,score.score from student,score where student.id=score.student_id and student.name='许仙';

案例二: 查询所有同学的总成绩,以及同学的个人信息

-- 成绩表对学生表是 n 对 1 关系,查询总成绩需要根据成绩表的同学 id 来进行分组的
select stu.sn,stu.name,stu.qq_mail,sum(sco.score) from student stu,score sco where stu.id=sco.student_id group by sco.student_id;

执行结果:

案例三: 查询所有同学的成绩,以及同学的个人信息。

-- 学生表、成绩表、课程表 3 张表关联查询
select stu.sn,stu.name,stu.qq_mail,sco.score,sco.course_id,cou.name from student stu,score sco,course cou where stu.id=sco.student_id and cou.id=sco.course_id;

运行结果:

1.2 外连接

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

语法:

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

案例: 查询所有同学的成绩,以及同学的个人信息。如果该同学没有成绩,也需要显示。

select stu.id,stu.sn,stu.name,stu.qq_mail,sco.score,sco.course_id,cou.name
from student stu left join score sco on stu.id=sco.student_id left join course cou on sco.course_id=cou.id
order by stu.id;

运行结果:

1.3 内连接和左右外连接的区别

假设两个表的每一条数据都是一一对应的,此时外连接和内连接是等价的。
如果有时候可能存在一些数据,没有对应关系,内外连接就有差别了。

例如:

内连接: 两个表内连接,有个没有成绩的同学没有显示出来。

左外连接: 一共 21 条记录,“老外学中文” 同学可以显示出来。

右外连接: 一共 21 条记录,“老外学中文” 同学可以显示出来。

观察案例可以发现,内连接的结果只包含在两张表都有体现的数据;
左外连接,左侧的表的数据是全的;
右外连接,右侧的表的数据是全的。


二、自连接

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

案例: 查询所有 “计算机原理” 成绩比 “Java” 成绩高的成绩信息。

select s1.student_id, s1.score as java, s2.score as '计算机原理'
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;-- join on 语句的写法来进行自连接查询
select s1.student_id,s1.score as java,s2.score as '计算机原理'
from score s1 join score s2
on s1.student_id=s2.student_id and s1.score < s2.score and s1.course_id=1 and s2.course_id=3;

运行结果:

以上查询只显示了成绩信息,要显示学生以及成绩信息,并且在一条语句显示:

SELECTstu.*,s1.score Java,s2.score 计算机原理
FROMscore s1JOIN score s2 ON s1.student_id = s2.student_idJOIN student stu ON s1.student_id = stu.idJOIN course c1 ON s1.course_id = c1.idJOIN course c2 ON s2.course_id = c2.idAND s1.score < s2.scoreAND c1.NAME = 'Java'AND c2.NAME = '计算机原理';

运行结果:


三、子查询

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

3.1 单行子查询

返回一行记录的子查询

查询与 “不想毕业” 同学的同班同学

select * from student where classes_id=(select classes_id from student where name='不想毕业');

3.2 多行子查询

返回多行记录的子查询

使用 in 范围匹配多行

查询 “语文” 或者 “英文” 课程的成绩信息

select * from score where course_id in (select id from course where name='语文' or name='英文');

执行结果:

另一种写法 exists

也可以完成多行子查询

select * from score
where exists(select score,course_id from course where(name='英文' or name='语文') and course.id=score.course_id
);

执行过程:

先执行外层查询,就会得到很多行记录。

每获取到外层查询的一行,就都会执行一次子查询的 SQL。

接下来,如果子查询的结果集合为空,那么外层查询的这一行记录,就被忽略。
如果子查询的结果集合非空,那么外层查询的这一行记录就会被记录。

exists 效果就是检测,先获取数据,在把数据一条一条的执行子查询 SQL,筛选掉不符合子查询的数据。

两种写法的区别

第一种基于 in 的写法,速度快,但是如果子查询的结果集合很大,内存放不下,就凉了。

第二种,基于 exists 的写法,速度慢,但是和内存的关系不大,哪怕子查询很大,也能保证执行出结果。

如果子查询结果集合比较小,优先使用第一种写法。

如果子查询结果集合比较大,并且外层查询的结果数量比较少,优先考虑第二种写法。

3.3 在 from 子句中使用子查询

子查询语句出现在 from 子句中。
这里要用到数据查询的技巧,把一个子查询当成一个临时表来使用。

查询所有比 “中文系2019级3班” 平均分高的成绩信息:

select avg(sco.score) score
from score sco join student stu on sco.student_id=stu.id join classes cls on stu.classes_id=cls.id
where cls.name='中文系2019级3班';

查询成绩表中,比以上临时表平均分高的成绩:

select * from score sco,(select avg(sco.score) score from score sco join student stu on sco.student_id=stu.id join classes cls on stu.classes_id=cls.id where cls.name='中文系2019级3班'
)tmp where sco.score > tmp.score;

四、合并查询

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

union

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

查询 id 小于 3,或者名字为 ‘英文’ 的课程

select * from course where id<3
union
select * from course where name='英文';

执行结果:

其实使用 or 来实现更加简单。

select * from course where id<3 or name='英文';

union all

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

查询 id 小于 3,或者名字为 ‘Java’ 的课程

select * from course where id<3 union all select * from course where name='Java';

运行结果:有重复行。

MySQL 表的增删改查(进阶篇②)· 联合查询 内连接 外连接 · 自连接 · 子查询 exists · 合并查询 union相关推荐

  1. MYSQL表的增删改查进阶(下)

    MYSQL表的增删改查进阶 4. 查询 4.1 聚合查询 4.1.1 聚合函数 4.1.2 group by字句 4.1.3 having 4.2 联合查询 4.2.1 内连接 4.2.2 外连接 4 ...

  2. 2.MySQL表的增删改查(进阶)

    这里写目录标题 MySQL表的增删改查(进阶) 1.数据库约束 2.表的设计 3.新增 4.查询 4.1 聚合查询 4.2 联合查询 5.内容重点总结 MySQL表的增删改查(进阶) 1.数据库约束 ...

  3. 数据库概论之MySQL表的增删改查1

    MySQL表的增删改查 1.MySQL表的CRUD 2.插入数据 2.1 语法 2.2 注意事项 3.查找语句 3.1 全列查找 3.2 指定列查询 3.3 指定查询字段为表达式 3.4 查询字段指定 ...

  4. MySQL表的增删改查(基础)

    MySQL表的增删改查(基础) 文章目录 MySQL表的增删改查(基础) 新增(`Create`) 查询(`Retrieve`) 更新(`Update`) 删除(`Delete`) 总结 注释:在SQ ...

  5. MySQL表的增删改查

    MySQL表的增删改查 CRUD 即增加(Create).查询(Retrieve).更新(Update).删除(Delete)四个单词的首字母缩写. 表的操作,是以一套记录为基本单位: 增.删只能是以 ...

  6. 【MySQL系列】 MySQL表的增删改查(进阶)

    目录 ??前言 ??一.数据库约束 ???1.1 约束类型 ???1.2 null约束 ???1.3 unique约束 ???1.4 default约束 ???1.5 primary key 约束 ? ...

  7. 【MySQL】(万字解析)MySQL表的增删改查(进阶-上)

    快速跳转✅ 1.数据库的约束 1.1 约束类型 1.2 NULL约束 1.3 UNIQUE:唯一约束 1.4 DEFAULT:默认值约束 1.5 PRIMARY KEY:主键约束 1.6 FOREIG ...

  8. php mysql表的增删改查,PHP 之Mysql增删改查操作案例

    1:user表: CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(32) NOT NULL, PR ...

  9. MySQL - 表的增删改查(约束+聚合、联合查询)

    本节目标: 数据库约束 表的关系 新增: 删除 修改 查询 1.数据库约束 1.1约束类型 NOT NULL -指示某列不能存储 NULL值. UNIQUE -保证某列的每行必须有唯一的值. DEFA ...

最新文章

  1. Java七步创建以JDBC连接数据库的程序
  2. GPT-4参数将达10兆!此表格预测全新语言模型参数将是GPT-3的57倍
  3. AX2009报表打印固定长度Barcode条码
  4. jQuery 中的 Ajax
  5. 在腾讯工作半年,我获得了什么?
  6. springcloud feign 服务调用其他服务_微服务实战——SpringCloud与Feign集成
  7. python填空题_Python题库-填空题
  8. HTML 去调table表单里面td之间的间距
  9. 屏幕为什么要正负压供电_焦炉煤气脱硫为什么要选择负压脱硫工艺?
  10. 电脑运行c语言时错误,电脑出现microsoft visual c++ runtime error 解决方法(多图)
  11. 浏览器内核信息和功能查看
  12. [渝粤教育] 西南科技大学 翻译 在线考试复习资料
  13. html怎么把正方形改成圆形,css怎样让div变成圆的?
  14. C语言怎么用char输出多个字母,c语言中char类型如何存放多个字符
  15. TCP可以从我们的视听感知中借鉴些什么
  16. 第五人格深渊金币每周更新时间
  17. 微信小程序点击查看大图
  18. 设计模式-设计原则-开闭原则是目标,里氏代换原则是基础,依赖倒转原则是手段...
  19. 20220509数据结构绿书读书笔记
  20. 王者荣耀小游戏1.0震撼上线!C++版

热门文章

  1. ognl表达式的简单用法
  2. 为什么计算机模拟试题无法评分,科目一电脑模拟打分答题
  3. python 做表格分析_Python 处理分析 128 张 Excel 表格竟不到3秒?| 附数据集
  4. 树莓派4 Ubuntu18.04安装xubuntu桌面 无线WIFI 及 ros melodic(解决apt update error,安装xubuntu error问题)
  5. 输入一个年份,输出是否为闰年。闰年的条件,又能被4整除但不能被100整除,或者能被400整除的年份都是闰年
  6. VSCode遇见的问题:chrome文件找不到/js中块级注释显示白色无效
  7. SitePoint播客#47:将死苹果
  8. Windows下使用GitHub Pages搭建hexo博客详细教程以及Next主题超全配置
  9. 枚举QQ或者TM进程、标题、窗口信息、QQ号码昵称等
  10. 50个好用的前端框架,千万收好以留备用!