我有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 |
+------+------+------+------+------+
这与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 |
+------+------+------+------+------+
与相同的行table_a LEFT JOIN table_b
。
完全没有连接可以为您提供所有内容的副本
No Join子句:如果您编写的表根本没有JOIN子句,只是用逗号隔开,那么您将以每种可能的组合在第二个表的每一行旁边写入第一个表的每一行:
> SELECT * FROM table_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连接类型示例”中得出的)