18、MySQL多表连查详解

MySQL的多表连查(即多表连接查询)对于数据库管理员、开发人员以及数据分析师来说都是非常重要的。对此,笔者专门写一文进行详细讲解,以便个人学习:

首先建立两张表用于数据验证:

 

1、笛卡尔积:

笛卡儿积(Cartesian product)是指在两个集合A和B之间的所有可能的有序对的集合。具体来说,如果A是一个集合,B也是一个集合,那么A和B的笛卡儿积A×B是一个新的集合,该集合中的元素是A中的元素和B中的元素的所有可能的有序对

例如,如果A = {a, b},B = {1, 2, 3},那么A和B的笛卡儿积A×B就是{(a,1), (a,2), (a,3), (b,1), (b,2), (b,3)}。在这个例子中,A×B包含了6个元素,每个元素都是一个有序对,其中第一个元素来自集合A,第二个元素来自集合B。

 

2、内连接INNER JOIN:

内连接根据两个表之间的共同字段进行匹配,并只返回那些在两个表中都存在匹配值的记录。如果某个表中的记录在另一个表中没有匹配的记录,则该记录不会出现在内连接的结果集中。

 

(1)、情况一:

SELECT * FROM `t_one` A INNER JOIN `t_two` B ON A.id = B.id

根据两表的id字段进行匹配,仅返回两个表之间存在匹配关系的行。

满足共有条件的id为1、2、3,匹配结果共9条数据:

  当id为1的匹配结果集:2x3=6

  当id为2的匹配结果集:1x2=2

  当id为3的匹配结果集:1x1=1

(2)、情况二:

SELECT * FROM `t_one` A INNER JOIN `t_two` B ON A.id = B.id AND A.id = 2

根据两表的id字段且左表id为1进行匹配,仅返回两个表之间存在匹配关系的行。

满足共有条件的id为2,匹配结果共2条数据:

  当id为2的匹配结果集:1x2=2

(3)、情况三:

SELECT * FROM `t_one` A INNER JOIN `t_two` B ON A.id = B.id WHERE A.id = 1

SQL执行过程通常是先从指定的表中获取数据(FROM子句),然后对获取的数据进行条件筛选(WHERE子句)。这种执行顺序有助于减少不必要的数据传输和计算成本,提高查询效率。FROM 子句包括左右连接(例如 LEFT JOIN、RIGHT JOIN 等)。

等价于查询首先进行连接,然后过滤结果集:

SELECT * FROM (SELECT A.id,A.`name`,B.id AS id2,B.`name` AS name2 FROM `t_one` A INNER JOIN `t_two` B ON A.id = B.id) C WHERE C.id2 = 1

 

3、左连接LEFT JOIN:

左连接(LEFT JOIN)是一种外连接,以左表为主表,左表从上到下进行匹配,返回左右表满足条件的匹配结果集。如果左表中的某一行在右表中没有匹配的行,则结果集中右表的部分将包含 NULL 值,左表正常返回。

左连接在正常使用情况下(即带有有效的连接条件)不会产生笛卡尔积。产生笛卡尔积的情况更常见于 CROSS JOIN 或在 JOIN 操作中省略了连接条件

 

(1)、情况一:

SELECT * FROM `t_one` A LEFT JOIN `t_two` B ON A.id = B.id

左连接以左边表为主表,左表从上到下进行匹配,返回左右表满足id值相等的匹配结果集。若右表不满足返回NULL,左表正常返回,共10条数据:

  当左表id为1时,满足的匹配结果集:2x3=6

  当左表id为2,满足的匹配结果集:1x2=2

  当左表id为3,满足的匹配结果集:1x1=1

  当左表id为6,满足的匹配结果集:右表不满足返回NULL,左表正常返回

(2)、情况二:

SELECT * FROM `t_one` A LEFT JOIN `t_two` B ON A.id = B.id AND A.id = 1

左连接以左边表为主表,左表从上到下进行匹配,同时返回左右表满足id值相等且左表id为1的匹配结果集,若右表不满足返回NULL,左表正常返回,共9条数据:

  当左表id为1时,满足的匹配结果集:2x3=6

  当左表id为2,满足的匹配结果集:右表不满足返回NULL,左表正常返回

  当左表id为3,满足的匹配结果集:右表不满足返回NULL,左表正常返回

  当左表id为6,满足的匹配结果集:右表不满足返回NULL,左表正常返回

(3)、情况三:

SELECT * FROM `t_one` A LEFT JOIN `t_two` B ON A.id = B.id WHERE B.id = 1

SQL执行过程通常是先从指定的表中获取数据(FROM子句),然后对获取的数据进行条件筛选(WHERE子句)。这种执行顺序有助于减少不必要的数据传输和计算成本,提高查询效率。FROM 子句包括左右连接(例如 LEFT JOIN、RIGHT JOIN 等)。

等价于查询首先进行连接,然后过滤结果集:

SELECT * FROM (SELECT A.id,A.`name`,B.id AS id2,B.`name` AS name2 FROM `t_one` A LEFT JOIN `t_two` B ON A.id = B.id) C WHERE C.id2 = 1

(4)常用应用:

查询仅左表存在的数据

SELECT * FROM `t_one` A LEFT JOIN `t_two` B ON A.id = B.id WHERE B.id IS NULL

 

4、右连接RIGHT JOIN:

右连接(RIGHT JOIN)是一种外连接,与左连接类似,此时以右表为主表,右表从上到下进行匹配,返回左右表满足条件的匹配结果集。如果右表中的某一行在左表中没有匹配的行,则结果集中左表的部分将包含 NULL 值,右表正常返回。

右连接在正常使用情况下(即带有有效的连接条件)不会产生笛卡尔积。产生笛卡尔积的情况更常见于 CROSS JOIN 或在 JOIN 操作中省略了连接条件

(1)、情况一:

SELECT * FROM `t_one` A RIGHT JOIN `t_two` B ON A.id = B.id

右连接以右边表为主表,右表从上到下进行匹配,返回左右表满足id值相等的匹配结果集。若左表不满足返回NULL,右表正常返回,共10条数据:

  当右表id为1时,满足的匹配结果集:3x2=6

  当右表id为2,满足的匹配结果集:2x1=2

  当右表id为3,满足的匹配结果集:1x1=1

  当右表id为4,满足的匹配结果集:左表不满足返回NULL,左表正常返回

(2)、情况二:

SELECT * FROM `t_one` A RIGHT JOIN `t_two` B ON A.id = B.id AND A.id = 1

右连接以右边表为主表,右表从上到下进行匹配,返回左右表满足id值相等且左表id为1的匹配结果集。若左表不满足返回NULL,右表正常返回,共10条数据:

  当右表id为1时,满足的匹配结果集:3x2=6

  当右表id为2,满足的匹配结果集:左表不满足返回NULL,左表正常返回

  当右表id为3,满足的匹配结果集:左表不满足返回NULL,左表正常返回

  当右表id为4,满足的匹配结果集:左表不满足返回NULL,左表正常返回

(3)、情况三:

SELECT * FROM `t_one` A RIGHT JOIN `t_two` B ON A.id = B.id WHERE A.id = 1

SQL执行过程通常是先从指定的表中获取数据(FROM子句),然后对获取的数据进行条件筛选(WHERE子句)。这种执行顺序有助于减少不必要的数据传输和计算成本,提高查询效率。FROM 子句包括左右连接(例如 LEFT JOIN、RIGHT JOIN 等)。

等价于查询首先进行连接,然后过滤结果集:

SELECT * FROM (SELECT A.id,A.`name`,B.id AS id2,B.`name` AS name2 FROM `t_one` A RIGHT JOIN `t_two` B ON A.id = B.id) C WHERE C.id = 1

(4)常用应用:

查询仅右表存在的数据

SELECT * FROM `t_one` A RIGHT JOIN `t_two` B ON A.id = B.id WHERE A.id IS NULL

 

5、全连接UNION:

全连接(Full Join)不是SQL中的标准连接类型,MySQL不支持。采用UNION 操作,可以用于合并两个查询的结果集,包括它们的交集和并集。

UNION操作用于合并两个或多个SELECT语句的结果集。它会删除重复的行,只返回唯一的行。如果需要保留重复的行,可以使用 UNION ALL

对于UNION操作,要求参与UNION的查询结果集的字段数必须相同,否则会出现语法错误。这是因为UNION是用来合并两个或多个查询结果集的,合并时要求每个查询结果的列数和数据类型必须相匹配,以便得到一个统一的结果集。

SELECT column1, column2

FROM table1

UNION

SELECT column1, column2

FROM table2;

 

6、多表逗号交叉连接:

多表逗号连接(Cross Join)和内连接(Inner Join)在某种程度上是类似的,但也有一些重要的区别:

(1)、多表逗号连接返回的结果是两个或多个表的笛卡尔积,即每个表的每一行都与其他表的每一行组合在一起。

(2)、内连接返回的结果是根据连接条件匹配的行,只有满足连接条件的行才会出现在结果集中。

 

 

posted on 2024-04-03 18:57  爱文(Iven)  阅读(14)  评论(0编辑  收藏  举报

导航