MySQL: 联接类型的快速分解

我想快速分析一下 MySQL 连接的类型。我知道这些,其余的我不知道他们是什么意思。

  • 逗号分隔(没错的缩写是什么?) : SELECT * FROM a, b WHERE b.id = a.beeId AND ...
  • 显示来自 a 的信息,即使 b: SELECT * FROM a LEFT OUTER JOIN b ON b.id = a.beeId WHERE ...中没有匹配

我见过其他的连接,但是想知道是什么使它们不同,什么是 INNER/OUTER,加入 LEFT会改变什么。

我已经知道了连接是如何工作的,我只想知道是否存在其他类型的连接,或者它们只是获得相同结果的不同方式。

139996 次浏览

根据你的评论,每个学校的简单定义可以在 W3Schools 上找到 每种类型的第一行简要说明了连接类型

  • JOIN: 当两个表中至少有一个匹配项时返回行
  • 左连接: 返回左表中的所有行,即使右表中没有匹配项
  • RightJOIN: 返回右表中的所有行,即使左表中没有匹配项
  • FULLJOIN: 当其中一个表中有匹配项时返回行

结束编辑

简而言之,逗号分隔了您给出的示例

SELECT * FROM a, b WHERE b.id = a.beeId AND ...

是从表 a 和表 b 中选择每条记录,逗号分隔表,这也可以用在诸如

SELECT a.beeName,b.* FROM a, b WHERE b.id = a.beeId AND ...

然后在示例中 b.id 列和 a.beeId 列匹配的行中获取指示信息。 因此在您的示例中,它将从表 a 和表 b 中获得所有信息,其中 b.id 等于 a.beeId。 在我的示例中,当 b.id 等于 a.beeId 时,它将从 b 表获得所有信息,并且只从 a.beeName 列获得信息。 请注意,还有一个 AND 子句,这将有助于完善您的结果。

对于一些关于 mySQL 连接和左连接的简单教程和解释,可以看看 Tizag 的 mySQL 教程。您还可以查看 基思 · J · 布朗的网站以获得关于连接的更多信息,这些信息也非常好。

我希望这能帮到你

在 mysql 中不存在完整的外部连接,您可能需要使用左连接和右连接的组合。

我有两张这样的桌子:

> SELECT * FROM table_a;
+------+------+
| id   | name |
+------+------+
|    1 | row1 |
|    2 | row2 |
+------+------+


> SELECT * FROM table_b;
+------+------+------+
| id   | name | aid  |
+------+------+------+
|    3 | row3 |    1 |
|    4 | row4 |    1 |
|    5 | row5 | NULL |
+------+------+------+

INNER JOIN 关注两个表

INNERJOIN 同时关注两个表,因此只有两个表都有一个行时才会获得一个行。如果有多个匹配对,则会得到多行。

> SELECT * FROM table_a a INNER JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | id   | name | aid  |
+------+------+------+------+------+
|    1 | row1 |    3 | row3 | 1    |
|    1 | row1 |    4 | row4 | 1    |
+------+------+------+------+------+

如果您反转顺序,则 INNER JOIN 与 INNER JOIN 没有区别,因为它同时关心两个表:

> SELECT * FROM table_b b INNER JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    4 | row4 | 1    |    1 | row1 |
+------+------+------+------+------+

得到相同的行,但是列的顺序不同,因为我们提到的表的顺序不同。

左连接只关心第一个表

LEFT JOIN 关心您给它的第一个表,而不太关心第二个表,因此您总是从第一个表中获取行,即使第二个表中没有对应的行:

> SELECT * FROM table_a a LEFT JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | id   | name | aid  |
+------+------+------+------+------+
|    1 | row1 |    3 | row3 | 1    |
|    1 | row1 |    4 | row4 | 1    |
|    2 | row2 | NULL | NULL | NULL |
+------+------+------+------+------+

在上面,您可以看到 table _ a 的所有行,尽管其中一些行与表 b 中的任何行都不匹配,但并不是 table _ b 的所有行——只有那些与 table _ a 中的某些行匹配的行。

如果我们颠倒表的顺序,LEFT JOIN 的行为会有所不同:

> SELECT * FROM table_b b LEFT JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    4 | row4 | 1    |    1 | row1 |
|    5 | row5 | NULL | NULL | NULL |
+------+------+------+------+------+

现在我们得到 table _ b 的所有行,但是只匹配 table _ a 的行。

RightJOIN 只关心第二个表

a RIGHT JOIN b得到的行与 b LEFT JOIN a完全相同。唯一的区别是列的默认顺序。

> SELECT * FROM table_a a RIGHT JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | id   | name | aid  |
+------+------+------+------+------+
|    1 | row1 |    3 | row3 | 1    |
|    1 | row1 |    4 | row4 | 1    |
| NULL | NULL |    5 | row5 | NULL |
+------+------+------+------+------+

这与我们在左连接部分看到的 table_b LEFT JOIN table_a相同。

同样地:

> SELECT * FROM table_b b RIGHT JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    4 | row4 | 1    |    1 | row1 |
| NULL | NULL | NULL |    2 | row2 |
+------+------+------+------+------+

table_a LEFT JOIN table_b相同的行。

没有加入会给你所有东西的副本

如果你写的表没有 JOIN 子句,只是用逗号分隔,那么第一个表的每一行都写在第二个表的每一行旁边,每一种可能的组合:

> SELECT * FROM table_b b, table_a;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    3 | row3 | 1    |    2 | row2 |
|    4 | row4 | 1    |    1 | row1 |
|    4 | row4 | 1    |    2 | row2 |
|    5 | row5 | NULL |    1 | row1 |
|    5 | row5 | NULL |    2 | row2 |
+------+------+------+------+------+

(这是从我的博客文章 SQL 连接类型的示例)