SQL 左连接行为

SQL LEFT JOIN behaviour

尝试获取 SQL LEFT JOIN 到 return NULL,其中在其他 table 中没有相应的行。

Table 1 - T1

id  n
1   aaa       
2   bbb       
3   ccc       

Table 2 - T2

t1_id   t3_id
1   1
2   1
3   1
1   2
3   2
2   3
3   3

在T2中,注意没有2-2或1-3的组合。

select * 
from t1
left join t2
on t1.id = t2.t1_id
order by t2.t3_id, t1_id

输出:

id  n   t1_id   t3_id
1   aaa         1   1
2   bbb         2   1
3   ccc         3   1
1   aaa         1   2
3   ccc         3   2
2   bbb         2   3
3   ccc         3   3

我原以为还有两行

1   aaa         null    null
2   bbb         null    null

...对应T2中前面提到的缺失组合

请注意 ORDER BY 只是为了方便 - 它对 returned 行没有影响。

请帮助我理解为什么会发生这种情况,以及如何解决它。

如果您想要结果集中 t2 中的所有行,它应该是 left join 中引用的第一个 table:

select * 
from t2 left join
     t1
     on t1.id = t2.t1_id
order by t2.t3_id, t2.t1_id;

编辑:

您似乎想要生成 原始数据中没有的新行。使用 cross join 生成行,然后 left join 将它们引入:

select t3.t3_id, t1.id, t1.n
from (select distinct t2.t3_id from t2) as t3 cross join
     t1 left join
     t2
     on t3.t3_id = t2.t3_id and t2.t1_id

或者,如果您确实想在 FROM 中首先引用 t1,您可以改用 RIGHT JOIN(我个人觉得这些不太直观,但有些人更喜欢它们,当涉及更多表时,它们确实有它们的用处):

SELECT * 
FROM t1
     RIGHT JOIN t2 ON t1.id = t2.t1_id
ORDER BY t2.t3_id,
         t1_id;
table1:
-------------
| id | name |
-------------
|  1 | john |
-------------
|  2 | mark |
-------------
|  3 | will |
-------------

table2:
-----------------
| t1_id | t3_id |
-----------------
|   1   |   3   |
-----------------
|   1   |   2   |
-----------------
|   3   |   1   |
-----------------

如果我想通过 table2 获取 table1:

SELECT t1.* 
FROM table2 as t2 
LEFT JOIN table1 as t1
ON t1.id = t2.t1_id
WHERE 1
ORDER BY t1.id ASC;

您将获得:

-------------
| id | name |
-------------
|  1 | john |
-------------
|  1 | john |
-------------
|  3 | will |
-------------

已编辑:

所以查询将得到表2中的所有内容,所以(t1_id: 1, t3_id: 3), (t1_id: 1, t3_id: 2 ), (t1_id: 3, t3_id: 1), 那么left join会将t1的id与t2中的t1_id和t1中的所有列return作为i进行比较写了 *.