mysql多表查询一般用什么_mysql多表查询一般用什么?

本文详细介绍了MySQL中多表查询的三种主要方式:交叉连接、内连接和外连接。交叉连接返回连接表的笛卡尔积,适用于无特定关联的表。内连接返回关联字段相符的记录,而外连接则会包含基表的所有记录,即使在参考表中没有对应项。左连接和右连接分别是外连接的两种形式,分别保留左表或右表的所有记录。在实际应用中,根据需求选择合适的连接方式至关重要。
摘要由CSDN通过智能技术生成

mysql多表查询一般用交叉连接、内连接和外连接。交叉连接返回连接表的笛卡尔积;内连接是组合两个表中的记录,返回关联字段相符的记录,即返回两个表的交集部分;外连接会先将连接的表分为基表和参考表,再以基表为依据返回满足和不满足条件的记录。

28e22f8cec95d69a6b641e218e3096ea.png

在关系型数据库中,表与表之间是有联系的,所以在实际应用中,经常使用多表查询。多表查询就是同时查询两个或两个以上的表。

在 MySQL 中,多表查询主要有交叉连接、内连接和外连接。

交叉连接

交叉连接(CROSS JOIN)一般用来返回连接表的笛卡尔积。

交叉连接的语法格式如下:SELECT FROM CROSS JOIN [WHERE子句]

或SELECT FROM , [WHERE子句]

语法说明如下:字段名:需要查询的字段名称。

:需要交叉连接的表名。

WHERE 子句:用来设置交叉连接的查询条件。

注意:多个表交叉连接时,在 FROM 后连续使用 CROSS JOIN 或,即可。以上两种语法的返回结果是相同的,但是第一种语法才是官方建议的标准写法。

当连接的表之间没有关系时,我们会省略掉 WHERE 子句,这时返回结果就是两个表的笛卡尔积,返回结果数量就是两个表的数据行相乘。需要注意的是,如果每个表有 1000 行,那么返回结果的数量就有 1000×1000 = 1000000 行,数据量是非常巨大的。

交叉连接可以查询两个或两个以上的表,为了让读者更好的理解,下面先讲解两个表的交叉连接查询。

示例

查询学生信息表和科目信息表,并得到一个笛卡尔积。

为了方便观察学生信息表和科目表交叉连接后的运行结果,我们先分别查询出这两个表的数据,再进行交叉连接查询。

1)查询 tb_students_info 表中的数据,SQL 语句和运行结果如下:mysql> SELECT * FROM tb_students_info;

+----+--------+------+------+--------+-----------+

| id | name | age | sex | height | course_id |

+----+--------+------+------+--------+-----------+

| 1 | Dany | 25 | 男 | 160 | 1 |

| 2 | Green | 23 | 男 | 158 | 2 |

| 3 | Henry | 23 | 女 | 185 | 1 |

| 4 | Jane | 22 | 男 | 162 | 3 |

| 5 | Jim | 24 | 女 | 175 | 2 |

| 6 | John | 21 | 女 | 172 | 4 |

| 7 | Lily | 22 | 男 | 165 | 4 |

| 8 | Susan | 23 | 男 | 170 | 5 |

| 9 | Thomas | 22 | 女 | 178 | 5 |

| 10 | Tom | 23 | 女 | 165 | 5 |

+----+--------+------+------+--------+-----------+

10 rows in set (0.00 sec)

2)查询 tb_course 表中的数据,SQL 语句和运行结果如下:mysql> SELECT * FROM tb_course;

+----+-------------+

| id | course_name |

+----+-------------+

| 1 | Java |

| 2 | MySQL |

| 3 | Python |

| 4 | Go |

| 5 | C++ |

+----+-------------+

5 rows in set (0.00 sec)

3)使用 CROSS JOIN 查询出两张表中的笛卡尔积,SQL 语句和运行结果如下:mysql> SELECT * FROM tb_course CROSS JOIN tb_students_info;

+----+-------------+----+--------+------+------+--------+-----------+

| id | course_name | id | name | age | sex | height | course_id |

+----+-------------+----+--------+------+------+--------+-----------+

| 1 | Java | 1 | Dany | 25 | 男 | 160 | 1 |

| 2 | MySQL | 1 | Dany | 25 | 男 | 160 | 1 |

| 3 | Python | 1 | Dany | 25 | 男 | 160 | 1 |

| 4 | Go | 1 | Dany | 25 | 男 | 160 | 1 |

| 5 | C++ | 1 | Dany | 25 | 男 | 160 | 1 |

| 1 | Java | 2 | Green | 23 | 男 | 158 | 2 |

| 2 | MySQL | 2 | Green | 23 | 男 | 158 | 2 |

| 3 | Python | 2 | Green | 23 | 男 | 158 | 2 |

| 4 | Go | 2 | Green | 23 | 男 | 158 | 2 |

| 5 | C++ | 2 | Green | 23 | 男 | 158 | 2 |

| 1 | Java | 3 | Henry | 23 | 女 | 185 | 1 |

| 2 | MySQL | 3 | Henry | 23 | 女 | 185 | 1 |

| 3 | Python | 3 | Henry | 23 | 女 | 185 | 1 |

| 4 | Go | 3 | Henry | 23 | 女 | 185 | 1 |

| 5 | C++ | 3 | Henry | 23 | 女 | 185 | 1 |

| 1 | Java | 4 | Jane | 22 | 男 | 162 | 3 |

| 2 | MySQL | 4 | Jane | 22 | 男 | 162 | 3 |

| 3 | Python | 4 | Jane | 22 | 男 | 162 | 3 |

| 4 | Go | 4 | Jane | 22 | 男 | 162 | 3 |

| 5 | C++ | 4 | Jane | 22 | 男 | 162 | 3 |

| 1 | Java | 5 | Jim | 24 | 女 | 175 | 2 |

| 2 | MySQL | 5 | Jim | 24 | 女 | 175 | 2 |

| 3 | Python | 5 | Jim | 24 | 女 | 175 | 2 |

| 4 | Go | 5 | Jim | 24 | 女 | 175 | 2 |

| 5 | C++ | 5 | Jim | 24 | 女 | 175 | 2 |

| 1 | Java | 6 | John | 21 | 女 | 172 | 4 |

| 2 | MySQL | 6 | John | 21 | 女 | 172 | 4 |

| 3 | Python | 6 | John | 21 | 女 | 172 | 4 |

| 4 | Go | 6 | John | 21 | 女 | 172 | 4 |

| 5 | C++ | 6 | John | 21 | 女 | 172 | 4 |

| 1 | Java | 7 | Lily | 22 | 男 | 165 | 4 |

| 2 | MySQL | 7 | Lily | 22 | 男 | 165 | 4 |

| 3 | Python | 7 | Lily | 22 | 男 | 165 | 4 |

| 4 | Go | 7 | Lily | 22 | 男 | 165 | 4 |

| 5 | C++ | 7 | Lily | 22 | 男 | 165 | 4 |

| 1 | Java | 8 | Susan | 23 | 男 | 170 | 5 |

| 2 | MySQL | 8 | Susan | 23 | 男 | 170 | 5 |

| 3 | Python | 8 | Susan | 23 | 男 | 170 | 5 |

| 4 | Go | 8 | Susan | 23 | 男 | 170 | 5 |

| 5 | C++ | 8 | Susan | 23 | 男 | 170 | 5 |

| 1 | Java | 9 | Thomas | 22 | 女 | 178 | 5 |

| 2 | MySQL | 9 | Thomas | 22 | 女 | 178 | 5 |

| 3 | Python | 9 | Thomas | 22 | 女 | 178 | 5 |

| 4 | Go | 9 | Thomas | 22 | 女 | 178 | 5 |

| 5 | C++ | 9 | Thomas | 22 | 女 | 178 | 5 |

| 1 | Java | 10 | Tom | 23 | 女 | 165 | 5 |

| 2 | MySQL | 10 | Tom | 23 | 女 | 165 | 5 |

| 3 | Python | 10 | Tom | 23 | 女 | 165 | 5 |

| 4 | Go | 10 | Tom | 23 | 女 | 165 | 5 |

| 5 | C++ | 10 | Tom | 23 | 女 | 165 | 5 |

+----+-------------+----+--------+------+------+--------+-----------+

50 rows in set (0.00 sec)

由运行结果可以看出,tb_course 和 tb_students_info 表交叉连接查询后,返回了 50 条记录。可以想象,当表中的数据较多时,得到的运行结果会非常长,而且得到的运行结果也没太大的意义。所以,通过交叉连接的方式进行多表查询的这种方法并不常用,我们应该尽量避免这种查询。

笛卡尔积

笛卡尔积(Cartesian product)是指两个集合 X 和 Y 的乘积。

例如,有 A 和 B 两个集合,它们的值如下:A = {1,2}

B = {3,4,5}

集合 A×B 和 B×A 的结果集分别表示为:A×B={(1,3), (1,4), (1,5), (2,3), (2,4), (2,5) };

B×A={(3,1), (3,2), (4,1), (4,2), (5,1), (5,2) };

以上 A×B 和 B×A 的结果就叫做两个集合的笛卡尔积。

并且,从以上结果我们可以看出:两个集合相乘,不满足交换率,即 A×B≠B×A。

A 集合和 B 集合的笛卡尔积是 A 集合的元素个数 × B 集合的元素个数。

多表查询遵循的算法就是以上提到的笛卡尔积,表与表之间的连接可以看成是在做乘法运算。在实际应用中,应避免使用笛卡尔积,因为笛卡尔积中容易存在大量的不合理数据,简单来说就是容易导致查询结果重复、混乱。

内连接

内连接(INNER JOIN)组合两个表中的记录,通过设置连接条件的方式,返回关联字段相符的记录,也就是返回两个表的交集(阴影)部分。

7310d80c867fe6dd90983f1a4d513f7b.png

内连接使用 INNER JOIN 关键字连接两张表,并使用 ON 子句来设置连接条件。如果没有连接条件,INNER JOIN 和 CROSS JOIN 在语法上是等同的,两者可以互换。

内连接的语法格式如下:SELECT FROM INNER JOIN [ON子句]

语法说明如下。字段名:需要查询的字段名称。

:需要内连接的表名。

INNER JOIN :内连接中可以省略 INNER 关键字,只用关键字 JOIN。

ON 子句:用来设置内连接的连接条件。

INNER JOIN 也可以使用 WHERE 子句指定连接条件,但是 INNER JOIN ... ON 语法是官方的标准写法,而且 WHERE 子句在某些时候会影响查询的性能。

多个表内连接时,在 FROM 后连续使用 INNER JOIN 或 JOIN 即可。

示例:

在 tb_students_info 表和 tb_course 表之间,使用内连接查询学生姓名和相对应的课程名称,SQL 语句和运行结果如下。mysql> SELECT s.name,c.course_name FROM tb_students_info s INNER JOIN tb_course c

-> ON s.course_id = c.id;

+--------+-------------+

| name | course_name |

+--------+-------------+

| Dany | Java |

| Green | MySQL |

| Henry | Java |

| Jane | Python |

| Jim | MySQL |

| John | Go |

| Lily | Go |

| Susan | C++ |

| Thomas | C++ |

| Tom | C++ |

+--------+-------------+

10 rows in set (0.00 sec)

在这里的查询语句中,两个表之间的关系通过 INNER JOIN 指定,连接的条件使用 ON 子句给出。

注意:当对多个表进行查询时,要在 SELECT 语句后面指定字段是来源于哪一张表。因此,在多表查询时,SELECT 语句后面的写法是表名.列名。另外,如果表名非常长的话,也可以给表设置别名,这样就可以直接在 SELECT 语句后面写上表的别名.列名。

外连接

外连接会先将连接的表分为基表和参考表,再以基表为依据返回满足和不满足条件的记录。

外连接可以分为左外连接和右外连接,下面根据实例分别介绍左外连接和右外连接。

左连接

左外连接又称为左连接,使用 LEFT OUTER JOIN 关键字连接两个表,并使用 ON 子句来设置连接条件。

左连接的语法格式如下:SELECT FROM LEFT OUTER JOIN

语法说明如下。字段名:需要查询的字段名称。

:需要左连接的表名。

LEFT OUTER JOIN:左连接中可以省略 OUTER 关键字,只使用关键字 LEFT JOIN。

ON 子句:用来设置左连接的连接条件,不能省略。

上述语法中,“表1”为基表,“表2”为参考表。左连接查询时,可以查询出“表1”中的所有记录和“表2”中匹配连接条件的记录。如果“表1”的某行在“表2”中没有匹配行,那么在返回结果中,“表2”的字段值均为空值(NULL)。

示例1

在进行左连接查询之前,我们先查看 tb_course 和 tb_students_info 两张表中的数据。SQL 语句和运行结果如下。mysql> SELECT * FROM tb_course;

+----+-------------+

| id | course_name |

+----+-------------+

| 1 | Java |

| 2 | MySQL |

| 3 | Python |

| 4 | Go |

| 5 | C++ |

| 6 | HTML |

+----+-------------+

6 rows in set (0.00 sec)

mysql> SELECT * FROM tb_students_info;

+----+--------+------+------+--------+-----------+

| id | name | age | sex | height | course_id |

+----+--------+------+------+--------+-----------+

| 1 | Dany | 25 | 男 | 160 | 1 |

| 2 | Green | 23 | 男 | 158 | 2 |

| 3 | Henry | 23 | 女 | 185 | 1 |

| 4 | Jane | 22 | 男 | 162 | 3 |

| 5 | Jim | 24 | 女 | 175 | 2 |

| 6 | John | 21 | 女 | 172 | 4 |

| 7 | Lily | 22 | 男 | 165 | 4 |

| 8 | Susan | 23 | 男 | 170 | 5 |

| 9 | Thomas | 22 | 女 | 178 | 5 |

| 10 | Tom | 23 | 女 | 165 | 5 |

| 11 | LiMing | 22 | 男 | 180 | 7 |

+----+--------+------+------+--------+-----------+

11 rows in set (0.00 sec)

在 tb_students_info 表和 tb_course 表中查询所有学生姓名和相对应的课程名称,包括没有课程的学生,SQL 语句和运行结果如下。mysql> SELECT s.name,c.course_name FROM tb_students_info s LEFT OUTER JOIN tb_course c

-> ON s.`course_id`=c.`id`;

+--------+-------------+

| name | course_name |

+--------+-------------+

| Dany | Java |

| Henry | Java |

| NULL | Java |

| Green | MySQL |

| Jim | MySQL |

| Jane | Python |

| John | Go |

| Lily | Go |

| Susan | C++ |

| Thomas | C++ |

| Tom | C++ |

| LiMing | NULL |

+--------+-------------+

12 rows in set (0.00 sec)

可以看到,运行结果显示了 12 条记录,name 为 LiMing 的学生目前没有课程,因为对应的 tb_course 表中没有该学生的课程信息,所以该条记录只取出了 tb_students_info 表中相应的值,而从 tb_course 表中取出的值为 NULL。

右连接

右外连接又称为右连接,右连接是左连接的反向连接。使用 RIGHT OUTER JOIN 关键字连接两个表,并使用 ON 子句来设置连接条件。

右连接的语法格式如下:SELECT FROM RIGHT OUTER JOIN

语法说明如下。字段名:需要查询的字段名称。

:需要右连接的表名。

RIGHT OUTER JOIN:右连接中可以省略 OUTER 关键字,只使用关键字 RIGHT JOIN。

ON 子句:用来设置右连接的连接条件,不能省略。

与左连接相反,右连接以“表2”为基表,“表1”为参考表。右连接查询时,可以查询出“表2”中的所有记录和“表1”中匹配连接条件的记录。如果“表2”的某行在“表1”中没有匹配行,那么在返回结果中,“表1”的字段值均为空值(NULL)。

示例2

在 tb_students_info 表和 tb_course 表中查询所有课程,包括没有学生的课程,SQL 语句和运行结果如下。mysql> SELECT s.name,c.course_name FROM tb_students_info s RIGHT OUTER JOIN tb_course c

-> ON s.`course_id`=c.`id`;

+--------+-------------+

| name | course_name |

+--------+-------------+

| Dany | Java |

| Green | MySQL |

| Henry | Java |

| Jane | Python |

| Jim | MySQL |

| John | Go |

| Lily | Go |

| Susan | C++ |

| Thomas | C++ |

| Tom | C++ |

| NULL | HTML |

+--------+-------------+

11 rows in set (0.00 sec)

可以看到,结果显示了 11 条记录,名称为 HTML 的课程目前没有学生,因为对应的 tb_students_info 表中并没有该学生的信息,所以该条记录只取出了 tb_course 表中相应的值,而从 tb_students_info 表中取出的值为 NULL。

多个表左/右连接时,在 ON 子句后连续使用 LEFT/RIGHT OUTER JOIN 或 LEFT/RIGHT JOIN 即可。

注:使用外连接查询时,一定要分清需要查询的结果,是需要显示左表的全部记录还是右表的全部记录,然后选择相应的左连接和右连接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值