多表查询
# 多表查询
在 MySQL 中 WHERE 子句的功能强大使得查询不局限于单表,更能使用多表查询。但是多表查询也增加了更多的限定条件,查询语句变得更加复杂繁琐,为此, MySQL 提供了更便捷的查询方式:连接查询、子查询以及正则表达式查询。
- 一对一 主键和外键 唯一性 (不可重复)
- 一对多 外键 可重复
- 多对多 需要借助第三张表中间表 中间表至少包含两列作为外键 分别关联两张表的主键
# 内连接查询
内连接包括相等连接和自然连接,最常见的例子是相等连接,也就是在 WHERE 子句中使用等号运算符,根据每个表共有列的值匹配两个表中的行。自然连接也常出现在实际应用中,它使用了 INNER JOIN 语句直接连接两个数据表的数据。
内连接查询的是两张表有交集的部分数据(有主外键关联的数据) 使用 inner join 关键字
-- 显式查询
select 列名 from 表名1 [inner] join 表名2 on 条件;
-- 隐式查询
select 列名 from 表名1,表名2 where 条件;
2
3
4
- ON 关键字后的条件含有匹配两个表中共有列
# 外连接查询
外连接生成的结果集不仅包含符合连接条件的行数据,而且包括左表(左外连接时的表)、右表(右外连接时的表)或两边连接表(全外连接时的表)中所有的数据行。
SELECT 字段名 FROM 数据表 1 LEFT|RIGHT [OUTER] JOIN 数据表 2 0N条件 ;
# 左外连接
左外连接是指返回左表中所有的记录,以及右表中符合连接条件的记录。当左表的某行记录在右表中没有匹配的记录时,右表中相关的记录将设为空值。
查询左表的全部数据,和左右两张表有交集部分的数据。 使用 关键字 left outer join
select 列名 from 表名1 left [outer] join 表名2 on 条件;
# 右外连接
右外连接是指返回右表中所有的记录,以及左表中符合连接条件的记录。当右表的某行记录在左表中没有匹配的记录时,左表中相关的记录将设为空值。
查询右表的全部数据,和左右两张表有交集部分的数据。 使用 关键字 right outer join
select 列名 from 表名1 right [outer] join 表名2 on 条件;
# 子查询
一个内层查询语句块可以嵌套在另外一个外层查询语句块的 WHERE 子句中,其中外层查询也称为父查询(或主查询)。内层查询也称子查询(或从查询)
查询语句中嵌套了查询语句,我们称为子查询
- 结果是单行单列 可以将结果加上运算符作为另外一条的查询条件
- 结果是多行单列 使用运算符 in 或者 not in 进行判断
- 结果是多行多列 作为一张虚拟表参与查询
# exists 关键字的子查询
用 EXISTS 关键字时,内层查询语句不返回查询的记录,而是返回布尔值。如果内层查询语句查询到满足条件的记录时,就返回一个真值( true ),否则,将返回一个假值( false )。当返回的值为 true 时,外层查询语句将进行查询,当返回的值为 false 时,外层查询语句不进行查询。
SELECT 字段 FROM 表名
WHERE EXISTS (SELECT 字段 FROM 表名 WHERE 条件);
2
# any 关键字的子查询
ANY 关键字表示满足其中任意一个条件,通常与比较运算符一起使用。使用 ANY 关键字时,只要满足内层查询语句返回的结果中的任意一个,就可以通过该条件来执行外层查询语句。
SELECT 字段 FROM 表名
WHERE 字段 比较运算符 ANY
(SELECT 字段 FROM 表名 WHERE
条件);
2
3
4
# all 关键字的子查询
ALL 关键字与 ANY 关键字用法一致,但是性质有所区别,它表示满足所有条件,通常与比较运算符一起使用。使用 ALL 关键字时,只有满足子查询返回的所有结果,才会继续执行外层查询。
SELECT 字段 FROM 表名
WHERE 字段 比较运算符 ALL
(SELECT 字段 FROM 表名 WHERE
条件);
2
3
4
# 合并查询
合并查询结果顾名思义是将多个 SELECT 语句的查询结果合并在一起。 MySQL 中可以使用 UNION 和 UNION ALL 关键字对查询结果进行合并。
使用 UNION 关键字可以将多个结果集合并到一起,并且会去除相同记录。
SELECT * FROM
tb_test
UNION
SELECT * FROM
tb_test1;
2
3
4
5
使用 UNION ALL 关键字也可以将多个结果集合并到一起,但是不会去除重复的数据。
SELECT * FROM
tb_test
UNION ALL
SELECT * FROM
tb_test1;
2
3
4
5
# 正则表达式查询
在 MySQL 中,使用 REGEXP 来匹配查询正则表达式
字段名 REGEXP '匹配方式';
| 模式字符 | 含义 | 应用举例 |
|---|---|---|
| ^ | 匹配以特定字符或字符串开头的记录 | 使用 “^” 表达式查询 tb_class 表中 class_id 字段以 “ B2” 开头的记录,查询语句如下:SELECT class_id FROM tb_class WHERE class_id REGEXP'^B2'; |
| $ | 匹配以特定字符或字符串结尾的记录 | 使用 “$” 表达式查询 tb_class 表中 class_id 字段以 “ 01” 结尾的记录,查询语句如下:SELECT class_id FROM tb_class WHERE class_id REGEXP'01$'; |
| . | 匹配任何单个字符,包括回车和换行符 | 使用 “.” 表达式查询 tb_class 表中 class_id 字段包含字符 5 的记录,查询语句如下:SELECT class_id FROM tb_class WHERE class_id REGEXP '.5'; |
| [字符集合] | 匹配字符集合中的任何一个字符 | 使用 “[]” 表达式查询 tb_class 表中 class_id 字段包含 10 的记录,查询语句如下:SELECT class_id FROM tb_class WHERE class_id REGEXP'[10]'; |
| S1|S2|S3 | 匹配 S1 、S2 和 S3 中的任意一个字符串 | 查询 tb_class 表中 class_id 字段包含 “B1”“B2” 或 “ B3” 的记录,查询语句如下:SELECT class_id FROM tb_class WHERE class_id REGEXP 'B1 |
| * | 匹配零个或多个在它前面的字符 | 使用 “*” 表达式查询 tb_class 表中 class_id 字段字符 “5” 前出现字符 “ B” 的记录,查询语句如下:SELECT class_id FROM tb_class WHERE class_id REGEXP 'B*5'; |
| + | 匹配前面的字符 1 次或多次 | 使用 “+” 表达式查询 tb_class 表中 class_id 字段字符 “5” 前出现过至少一次字符 “B” 的记录,查询语句如下:SELECT class_id FROM tb_class WHERE class_id REGEXP 'B+5'; |
| 字符串 {n} | 匹配字符串出现 n 次 | 使用 {n} 表达式查询 tb_class 表中 class_id 字段中连续出现 2 次字符 “ 0” 的记录,查询语句如下:SELECT class_id FROM tb_class WHERE class_id REGEXP'0 {2}'; |
| 字符串 {m,n} | 匹配字符串出现至少 m 次,最多 n 次 | 使用 {m,n} 表达式查询 tb_class 表中 class_id 字段中至少出现 1 次最多出现 2 次字符 “2” 的记录,查询语句如下:SELECT class_id FROM tb_class WHERE class_id REGEXP'2 {1,2}'; |
| <字符串> | 匹配包含字符串的文本 | 使用 “< 字符串>” 表达式查询 tb_class 表中 class_id 字段包含字符串 “ B5” 的记录,查询语句如下:SELECT class_id FROM tb_class WHERE class_id REGEXP'B5'; |
# 自关联查询
在同一张表中数据有关联性,我们可以当成多个表来查询
配合内外连接使用