当前位置:网站首页>MySQL数据查询 - 联合查询
MySQL数据查询 - 联合查询
2022-07-29 20:17:00 【骆驼胡杨】
联合查询
1. 内连接查询
内连接查询
在实际开发中,我们会联合多个表来实现查询,比如把班级表和学生表联合起来就同时可以看到班级、老师和学员的信息,一个班级表:
这种只有2张表匹配的行才能显示的连接方式在Mysql 中称之为内连接: INNER JOIN
在MySQL中内连接数据查询通过“INNER JOIN…ON”语句来实现,语法形式如下所示。SELECT field1,field2,…,fieldn FROM tablename1 INNER JOIN tablename2 [INNER JOIN tablenamen] ON CONDITION;其中,参数fieldn表示要查询的字段名,来源于所连接的表tablename1和tablename2,关键字INNER JOIN表示表进行内连接,参数CONDITION表示进行匹配的条件。
mysql> CREATE TABLE class(id int PRIMARY KEY, name varchar(128), teacher varchar(64)); #创建班级表 class mysql> insert into class values(101, '萌新一班', '张三'),(102, '萌新二班', '李四'),(103, '萌新三班', '王五'); #往班级表中插入多条记录 mysql> CREATE TABLE student(id int, name varchar(64), class_id int, sex enum('F','M')); #创建学生表 mysql> insert into student values(1,'小花',101,'M'),(2,'小红',102, 'F'),(3,'小军',102,'F'),(4,'小白',101,'F'); #往学生表中插入多条记录 mysql> select * from class inner join student on class.id = student.class_id; #查询class 表和student 表中班级字段相同的记录并进行内连接 +-----+----------+---------+------+------+----------+------+ | id | name | teacher | id | name | class_id | sex | +-----+----------+---------+------+------+----------+------+ | 101 | 萌新一班 | 张三 | 1 | 小花 | 101 | M | | 102 | 萌新二班 | 李四 | 2 | 小红 | 102 | F | | 102 | 萌新二班 | 李四 | 3 | 小军 | 102 | F | | 101 | 萌新一班 | 张三 | 4 | 小白 | 101 | F | +-----+----------+---------+------+------+----------+------+ mysql> select * from class as a inner join student as b where a.id = b.class_id; #同上,使用别名查询当表名特别长时,直接使用表名很不方便,或者在实现自连接操作时,直接使用表名无法区别表。为了解决这一类问题,MySQL提供了一种机制来为表取别名,具体语法如下:
SELECT field1, field2, ...,fieldn [AS] otherfieldn FROM tablename1 [AS] othertablename1, ..., Tablenamen [AS] othertablenamen ... where othertablename1.fieldx = othertablenamen.fieldx ... ; mysql> select s.id, s.name, s.class_id, s.sex, c.id, c.name, c.teacher from class AS c inner join student AS s on c.id=s.class_id; 其中,参数tablename*为表原来的名字,参数othertablename*为新表名,之所以要为表设置新的名字,是为了让SQL语句代码更加直观、更加人性化和实现更加复杂的功能。自连接
内连接查询中存在一种特殊的等值连接——自连接。所谓自连接,就是指表与其自身进行连接。
如:查询学生 ”小红 ”所在班级的其他学生,SQL语句如下:mysql> select * from student s1 inner join student s2 on s1.class_id = s2.class_id and s2.name= '小红'; #查询学生 ”小红 ”所在班级的其他学生 +------+------+----------+------+------+------+----------+------+ | id | name | class_id | sex | id | name | class_id | sex | +------+------+----------+------+------+------+----------+------+ | 2 | 小红 | 102 | F | 2 | 小红 | 102 | F | | 3 | 小军 | 102 | F | 2 | 小红 | 102 | F | +------+------+----------+------+------+------+----------+------+等值连接
内连接查询中的等值连接就是在关键字ON后的匹配条件中通过等于关系运算符(=)来实现等值条件。mysql> select * from class as a inner join student as b where a.id = b.class_id; +-----+----------+---------+------+------+----------+------+ | id | name | teacher | id | name | class_id | sex | +-----+----------+---------+------+------+----------+------+ | 101 | 萌新一班 | 张三 | 1 | 小花 | 101 | M | | 102 | 萌新二班 | 李四 | 2 | 小红 | 102 | F | | 102 | 萌新二班 | 李四 | 3 | 小军 | 102 | F | | 101 | 萌新一班 | 张三 | 4 | 小白 | 101 | F | +-----+----------+---------+------+------+----------+------+不等值连接
内连接查询中的不等连接就是在关键字ON后的匹配条件中通过除了等于关系运算符来实现不等条件外,还可以使用关系运算符,包含“>”“>=”“<”“<=”和“!=”等运算符号。mysql> select * from class as a inner join student as b where a.id != b.class_id; +-----+----------+---------+------+------+----------+------+ | id | name | teacher | id | name | class_id | sex | +-----+----------+---------+------+------+----------+------+ | 102 | 萌新二班 | 李四 | 1 | 小花 | 101 | M | | 103 | 萌新三班 | 王五 | 1 | 小花 | 101 | M | | 101 | 萌新一班 | 张三 | 2 | 小红 | 102 | F | | 103 | 萌新三班 | 王五 | 2 | 小红 | 102 | F | | 101 | 萌新一班 | 张三 | 3 | 小军 | 102 | F | | 103 | 萌新三班 | 王五 | 3 | 小军 | 102 | F | | 102 | 萌新二班 | 李四 | 4 | 小白 | 101 | F | | 103 | 萌新三班 | 王五 | 4 | 小白 | 101 | F | +-----+----------+---------+------+------+----------+------+
2.外连接查询
外连接查询
当我们在查询数据时,要求返回所操作表中至少一个表的所有数据记录,通过SQL语句“OUTER JOIN…ON”来实现。外连接数据查询语法形式如下:SELECT field1,field2,…,fieldn FROM tablename1 LEFT|RIGHT [OUTER] JOIN tablename2 ON CONDITION 在上述语句中,参数fieldn表示所要查询的字段名字,来源于所连接的表tablename1和tablename2,关键字OUTER JOIN表示表进行外连接,参数CONDITION表示进行匹配的条件。外连接查询可以分为以下两类:
(1)左外连接
外连接查询中的左外连接,就是指新关系中执行匹配条件时,以关键字LEFT JOIN左边的表为参考表。左连接的结果包括LEFT OUTER字句中指定的左表的所有行,而不仅仅是连接列所匹配的行,如果左表的某行在右表中没有匹配行,则在相关联的结果行中,右表的所有选择列表均为空值。
例如:查询所有学生的学号、姓名、班级编号、性别、班级名、班主任信息,具体SQL语句如下://左外连接查询所有班级的学员信息 mysql> select * from class as c left join student as s on c.id=s.class_id; +-----+----------+---------+------+------+----------+------+ | id | name | teacher | id | name | class_id | sex | +-----+----------+---------+------+------+----------+------+ | 101 | 萌新一班 | 张三 | 1 | 小花 | 101 | M | | 101 | 萌新一班 | 张三 | 4 | 小白 | 101 | F | | 102 | 萌新二班 | 李四 | 2 | 小红 | 102 | F | | 102 | 萌新二班 | 李四 | 3 | 小军 | 102 | F | | 103 | 萌新三班 | 王五 | NULL | NULL | NULL | NULL | +-----+----------+---------+------+------+----------+------+ //左外连接查询所有学员对应的班级信息 mysql> select * from student as s left join class as c on c.id=s.class_id; +------+------+----------+------+------+----------+---------+ | id | name | class_id | sex | id | name | teacher | +------+------+----------+------+------+----------+---------+ | 1 | 小花 | 101 | M | 101 | 萌新一班 | 张三 | | 2 | 小红 | 102 | F | 102 | 萌新二班 | 李四 | | 3 | 小军 | 102 | F | 102 | 萌新二班 | 李四 | | 4 | 小白 | 101 | F | 101 | 萌新一班 | 张三 | +------+------+----------+------+------+----------+---------+(2)右外连接
外连接查询中的右外连接在新关系中执行匹配条件时,以关键字RIGHT JOIN右边的表为参考表,如果右表的某行在左表中没有匹配行,左表将返回空值。
例如:查询所有班级的所有学生信息。具体SQL语句如下://右外连接查询所有班级对应的学员信息 mysql> select * from student as s right join class as c on c.id=s.class_id; +------+------+----------+------+-----+----------+---------+ | id | name | class_id | sex | id | name | teacher | +------+------+----------+------+-----+----------+---------+ | 1 | 小花 | 101 | M | 101 | 萌新一班 | 张三 | | 4 | 小白 | 101 | F | 101 | 萌新一班 | 张三 | | 2 | 小红 | 102 | F | 102 | 萌新二班 | 李四 | | 3 | 小军 | 102 | F | 102 | 萌新二班 | 李四 | | NULL | NULL | NULL | NULL | 103 | 萌新三班 | 王五 | +------+------+----------+------+-----+----------+---------+ //右外连接查询所有学员对应的班级信息 mysql> select * from class as c right join student as s on c.id=s.class_id; +------+----------+---------+------+------+----------+------+ | id | name | teacher | id | name | class_id | sex | +------+----------+---------+------+------+----------+------+ | 101 | 萌新一班 | 张三 | 1 | 小花 | 101 | M | | 102 | 萌新二班 | 李四 | 2 | 小红 | 102 | F | | 102 | 萌新二班 | 李四 | 3 | 小军 | 102 | F | | 101 | 萌新一班 | 张三 | 4 | 小白 | 101 | F | +------+----------+---------+------+------+----------+------+
3.合并查询数据记录
在MySQL中通过关键字UNION来实现合并操作,即可以通过其将多个SELECT语句的查询结果合并在一起,组成新的关系。在MySQL软件中,合并查询数据记录可通过SQL语句UNION来实现,具体语法形式如下:
SELECT field1,field2,…,fieldn FROM tablename1
UNION | UNION ALL
SELECT field1,field2,…,fieldn FROM tablename2
UNION | UNION ALL SELECT field1,field2,…,fieldn ;
注意: 多个选择语句select 的列数相同就可以合并,union和union all的主要区别是union all是把结果集直接合并在一起,而union 是将union all后的结果再执行一次distinct,去除重复的记录后的结果。
//查询班级表所有班级id和老师, 学生表中所有学生id和学生姓名
mysql> select id AS class_id, teacher AS people from class UNION ALL select class_id AS class_id, name AS people from student;
+----------+--------+
| class_id | people |
+----------+--------+
| 101 | 张三 |
| 102 | 李四 |
| 103 | 王五 |
| 101 | 小花 |
| 102 | 小红 |
| 102 | 小军 |
| 101 | 小白 |
+----------+--------+
4.子查询
所谓子查询,是指在一个查询中嵌套了其他的若干查询,即在一个SELECT查询语句的WHERE或FROM子句中包含另一个SELECT查询语句。在查询语句中,外层SELECT查询语句称为主查询,WHERE子句中的SELECT查询语句被称为子查询,也被称为嵌套查询。
通过子查询可以实现多表查询,该查询语句中可能包含IN、ANY、ALL和EXISTS等关键字,除此之外还可能包含比较运算符。理论上,子查询可以出现在查询语句的任意位置,但是在实际开发中子查询经常出现在WHERE和FROM子句中。
带比较运算符的子查询
子查询可以使用比较运算符。这些比较运算符包括=、!=、>、>=、<、<=和<>等。其中,<>与!=是等价的。比较运算符在子查询中使用得非常广泛,如查询分数、年龄、价格和收入等。
例如:查询student 表中“小花”所在班级班主任的名字。SQL语句如下://使用比较运算= 查找学生小花的 班级 mysql> select * from class where id = (select class_id from student where name='小花'); +-----+----------+---------+ | id | name | teacher | +-----+----------+---------+ | 101 | 萌新一班 | 张三 | +-----+----------+---------+ 注意:使用比较运算符时,select 子句获得的记录数不能大于1条!!!带关键字IN的子查询
一个查询语句的条件可能落在另一个SELECT语句的查询结果中,这时可以使用IN关键字,SQL示例如下:
NOT IN的用法与IN相同。
例如:查询student 表中“小花”所在班级班主任的名字。SQL语句如下://使用IN查找学生小花的 班级 mysql> select * from class where id IN (select class_id from student where name='小花'); +-----+----------+---------+ | id | name | teacher | +-----+----------+---------+ | 101 | 萌新一班 | 张三 | +-----+----------+---------+ //使用IN查找学生'小%'的 班级 mysql> select * from class where id IN (select class_id from student where name like '小%'); +-----+----------+---------+ | id | name | teacher | +-----+----------+---------+ | 101 | 萌新一班 | 张三 | | 102 | 萌新二班 | 李四 | +-----+----------+---------+带关键字EXISTS的子查询
关键字EXISTS表示存在,后面的参数是一个任意的子查询,系统对子查询进行运算以判断它是否返回行;如果至少返回一行,那么EXISTS的结果为true,此时外层语句将进行查询;如果子查询没有返回任何行,那么EXISTS返回的结果是false,此时外层语句将不进行查询。
例如:如果102班存在学生记录,就查询102班的班级信息的记录。SQL示例语句如下://如果学生表中有102班的学生, 就显示102班的班级信息, 否则就不显示 mysql> select * from class where id=102 and exists (select * from student where class_id=102); +-----+----------+---------+ | id | name | teacher | +-----+----------+---------+ | 102 | 萌新二班 | 李四 | +-----+----------+---------+ //如果学生表中有103班的学生, 就显示102班的班级信息, 否则就不显示 mysql> select * from class where id=102 and exists (select * from student where class_id=103); Empty set (0.00 sec)带关键字ANY的子查询
关键字ANY表示满足其中任一条件。使用关键ANY时,只要满足内层查询语句返回的结果中的任何一个就可以通过该条件来执行外层查询语句。例如,需要查询哪些学生可以获取奖学金,那么首先要有一张奖学金表,从表中查询出各种奖学金要求的最低分,只要一个同学的乘积大于等于不同奖学金最低分的任何一个,这个同学就可以获得奖学金。关键字ANY通常和比较运算符一起使用。例如,“>ANY”表示大于任何一个值,“=ANY”表示等于任何一个值。
例如:查询数据库school的表student中哪些学生可以获得奖学金。学生的成绩达到其中任何一项奖学金规定的分数即可,SQL语句示例如下:mysql> create table grade(id int, name varchar(64), math tinyint, chinese tinyint, english tinyint); #创建成绩表 mysql> insert into grade values(1, '甲', 80, 87, 91, 1), (2, '乙', 72, 64, 89, 2),(3, '丙', 54, 69, 79, 2), (4, '丁', 79, 79, 89, 1); mysql> create table scholarship (score int, level varchar(64)); #创建奖学金表 mysql> insert into scholarship values(240, '二等奖'),(257,'一等奖'); //查询grade表中所有成绩加起来大于score的学生 mysql> select id, name, math+chinese+english total from grade where math+chinese+english>=ANY(select score from scholarship); +----+------+-------+ | id | name | total | +----+------+-------+ | 1 | 甲 | 258 | | 4 | 丁 | 247 | +----+------+-------+带关键字ALL的子查询
关键字ALL表示满足所有条件。使用关键字ALL时,只有满足内层查询语句返回的所有结果才可以执行外层查询语句。例如,需要查询哪些同学能够获得一等奖学金,首先要从奖学金表中查询出各种奖学金要求的最低分。因为一等奖学金要求的分数最高,只有当成绩高于所有奖学金最低分时,这个同学才可能获得一等奖学金。关键字ALL也经常与比较运算符一起使用。例如,“>ALL”表示大于所有值,“<ALL”表示小于所有值。
例如:查询数据库school的表student中哪些学生可以获得一等奖学金,即学生的总成绩要达到一等奖学金规定的分数,而一等奖学金是最高奖学金。SQL语句示例如下://查询grade表中所有成绩加起来只能拿一等奖的学生 mysql> select id, name, math+chinese+english total from grade where math+chinese+english>=ALL(select score from scholarship); +----+------+-------+ | id | name | total | +----+------+-------+ | 1 | 甲 | 258 | +----+------+-------+ //查询grade表中所有成绩加起来没有拿到奖学金的学生 mysql> select id, name, math+chinese+english total from grade where math+chinese+english<ALL(select score from scholarship); +----+------+-------+ | id | name | total | +----+------+-------+ | 2 | 乙 | 225 | | 3 | 丙 | 202 | +----+------+-------+
边栏推荐
- 【无标题】
- 7 行代码搞崩溃 B 站,原因令人唏嘘!
- JSP Servlet JDBC MySQL CRUD Sample Tutorial
- ES6用法,面试大全
- 解析掌握现代化少儿编程实操能力
- 双功能RGD-TAT修饰DNA纳米胶束|聚苯胺纳米线修饰DNA(PAINW/DNA)
- Kotlin - 协程作用域 CoroutineScope、协程构建器 CoroutineBuilder、协程作用域函数 CoroutineScope Functiom
- 如何让 x == 1 && x == 2 && x == 3 等式成立
- 荧光量子点修饰siRNA-QDs|纳米金修饰siRNA-Au(RNA修饰方式方法)
- uri与url的区别简单理解(uri和url有什么区别)
猜你喜欢

conda虚拟环境 | install 与 list 问题

怎么实现您的个人知识库?

LOG4J 学习

Expert advice | How to formulate a growth strategy for survival in an economic downturn

378. 有序矩阵中第 K 小的元素

.NET 6.0中使用Identity框架实现JWT身份认证与授权
![[GXYCTF2019] ban dolls](/img/91/3f64bebd13a8b13fbb387c2acf8618.png)
[GXYCTF2019] ban dolls

从专业角度分析国内创客教育发展

JMeter使用教程(二)

Thesis writing strategy | how to write an academic research paper
随机推荐
Omni-channel e-commerce | How can well-known domestic cosmeceuticals seize the opportunity to achieve rapid growth?
剑指 Offer II 097. 子序列的数目
七个易犯的 IT 管理错误—以及如何避免
7 行代码搞崩溃 B 站,原因令人唏嘘!
940. 不同的子序列 II
JMeter使用教程(一)
offsetwidth111[easy to understand]
海量数据查询方案mysql_Mysql海量数据存储和解决方案之二—-Mysql分表查询海量数据…[通俗易懂]
The ambition of glory: "high-end civilians" in a smart world
Verilog的时间格式系统任务----$printtimescale、$timeformat
指定宽度截取字符串
软件开发模式有哪些(软件工程开发模式)
探索创客教育在线管理实施体系
internship:利用easypoi将excel表数据导入导出
关于论青少年尽早学少儿编程之说
【数据库】mysql日期格式转换
核壳二氧化钛纳米颗粒修饰DNA|二氢杨梅素修饰DNA药物|相关介绍
C language learning books (improvement)
LOG4J 学习
R语言对airbnb数据nlp文本挖掘、地理、词云可视化、回归GAM模型、交叉验证分析