MySQL:连接类型的快速细分

Bry*_*eld 149 mysql join

我想快速细分一下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改变的东西.

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

Ruf*_*nus 446

在G +上找到
(c)在G +"数据可视化"上找到

或者查看以下链接以获得良好的概述:

http://www.khankennels.com/blog/index.php/archives/2007/04/20/getting-joins/

http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html

  • 问题是关于MySQL的具体问题.MySQL不支持FULL OUTER连接. (38认同)
  • @denis:仔细看看codinghorror.com链接:`还有一个笛卡尔积或交叉连接,据我所知,它不能表示为维恩图: (11认同)
  • +1,但两者都缺少`cross join`,这是一个笛卡尔积. (3认同)
  • 当然,这应该是不发布这种格言的理由.*叹* (2认同)

小智 26

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

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

结束编辑

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

SELECT * FROM a, b WHERE b.id = a.beeId AND ...
Run Code Online (Sandbox Code Playgroud)

从表a和b中选择每个记录,用逗号分隔表,这也可以在列中使用

SELECT a.beeName,b.* FROM a, b WHERE b.id = a.beeId AND ...
Run Code Online (Sandbox Code Playgroud)

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

有关mySQL连接和左连接的一些简单教程和解释,请查看Tizag的mySQL教程.您还可以查看Keith J. Brown的网站,了解有关连接的更多信息.

我希望这可以帮助你

  • mysql中没有FULL JOIN,所以这些链接不是很有用。 (2认同)

And*_*aam 12

我有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 |
+------+------+------+
Run Code Online (Sandbox Code Playgroud)

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    |
+------+------+------+------+------+
Run Code Online (Sandbox Code Playgroud)

如果颠倒顺序,它对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 |
+------+------+------+------+------+
Run Code Online (Sandbox Code Playgroud)

您获得相同的行,但列的顺序不同,因为我们以不同的顺序提到了表.

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 |
+------+------+------+------+------+
Run Code Online (Sandbox Code Playgroud)

上面你可以看到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 |
+------+------+------+------+------+
Run Code Online (Sandbox Code Playgroud)

现在我们得到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 |
+------+------+------+------+------+
Run Code Online (Sandbox Code Playgroud)

这与table_b LEFT JOIN table_a我们在LEFT JOIN部分中看到的行相同.

同理:

> 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 |
+------+------+------+------+------+
Run Code Online (Sandbox Code Playgroud)

与行相同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 |
+------+------+------+------+------+
Run Code Online (Sandbox Code Playgroud)

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


小智 11

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