ChatGPT解决这个技术问题 Extra ChatGPT

MySQL:连接类型的快速细分[重复]

这个问题在这里已经有了答案:“INNER JOIN”和“OUTER JOIN”有什么区别? (28 个回答) 1 年前关闭。

我想快速了解一下 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 确实会改变一些事情。

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


7
700 Software

根据您的评论,最好在 W3Schools 中找到每种类型的简单定义。每种类型的第一行给出了连接类型的简要说明

JOIN:当两个表中至少有一个匹配时返回行 LEFT JOIN:返回左表中的所有行,即使右表中没有匹配项 RIGHT JOIN:返回右表中的所有行,即使有左表中没有匹配项 FULL JOIN:当其中一个表中存在匹配项时返回行

结束编辑

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

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 教程。您还可以查看 Keith J. Brown's website 以了解有关连接的更多信息,这也是相当不错的。

我希望这可以帮助你


碰巧我已经知道了这一切。我实际上是在寻找存在的连接类型。抱歉,我不清楚我知道什么。但我并不是为了快速总结而寻找冗长的文档。
答案中的另一个参考......可能更多的是你想要的伴侣。
为该编辑 +1。我并不像某些人那样对 W3Schools 有偏见。也许我没有看到太多不好的一面,或者这只是一场“圣战”。另外,我在 W3Schools 的内容中进行了编辑,希望您不介意,但请随意进行您喜欢的任何编辑。接受的答案中的所有这些视觉效果都很好,但有些实际上是相同连接的变体。这是一个很好的选择。
谢谢乔治,我一点也不介意,只要编辑是正确的!我相信人们需要找到适合他们的资源,或多或少的信息,大量的例子或没有。 W3Schools 准确而简洁,他们往往也有很好的例子,Tizag 也是类似的。放轻松队友
mysql 中没有 FULL JOIN,所以这些链接不是很有用。
M
Martijn Pieters

我有 2 个这样的表:

> 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 关心两个表

INNER JOIN 关心两个表,所以如果两个表都有一个,你只会得到一行。如果有多个匹配对,您将获得多行。

> 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 没有影响,因为它关心两个表:

> 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 只关心第一个表

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 的行。

RIGHT JOIN 只关心第二张表

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 |
+------+------+------+------+------+

这与我们在 LEFT JOIN 部分中看到的 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 |
+------+------+------+------+------+

(这来自我的博文 Examples of SQL join types


@Anu此答案与大多数答案具有相同的零散不完整描述。它实际上并没有说明输出是输入的函数。另请参阅建议的副本中的几乎所有答案 &我在两个页面上的评论。另请参阅我的答案。 PS 巧合的是,我从昨天 re reviewed edit size 才看到这个(当然在 Meta Stack OverflowMeta Stack Exchange 有更多相关的帖子。)
I
IBEANS

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