MySQL:连接类型的快速细分

时间:2011-06-09 14:49:46

标签: 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会改变一些事情。

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

4 个答案:

答案 0 :(得分:423)

答案 1 :(得分:25)

根据您的评论,每个的简单定义最好在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以获取有关连接的更多信息。

我希望这有助于你

答案 2 :(得分:11)

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

答案 3 :(得分:8)

我有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