这是我的表结构:SQL Fiddle
-- returns 3 rows
SELECT t1.id, t2.id
FROM mytable as t1
LEFT JOIN mytable as t2 ON t1.related = t2.id;
-- returns 4 rows
SELECT t1.id, t2.id
FROM mytable as t1
LEFT JOIN mytable as t2 ON t1.id = t2.related;
我有两个问题:
self-join
这些查询几乎相似,而且是3
。但正如您在小提琴中看到的那样,第一个查询返回4
行,第二个返回LEFT JOIN
行。这不是我所期待的。我认为结果应该完全一样。
您能否解释一下const id = 1
const url = "https://oversight-ws.herokuapp.com/api/politicians/" + id + "/rating"
在后台如何运作?
答案 0 :(得分:1)
LEFT JOIN
表示从左表中获取所有行,如果右表中存在匹配,则只返回,以返回这些行。如果没有匹配项,则返回NULL
。
让我们看一下数据集在没有条件的情况下加入自身时的样子。 (注意,下面提到了星号和长号。)
+-------+------------+-------+------------+
| t1.id | t1.related | t2.id | t2.related |
+-------+------------+-------+------------+
| 1 | NULL | 1 | NULL |
+| 1 | NULL | 2 | 1 |
+| 1 | NULL | 4 | 1 |
*| 2 | 1 | 1 | NULL |
| 2 | 1 | 2 | 1 |
| 2 | 1 | 4 | 1 |
*| 4 | 1 | 1 | NULL |
| 4 | 1 | 2 | 1 |
| 4 | 1 | 4 | 1 |
+-------+------------+-------+------------+
在这两种情况下左表都是t1
。
在第一个查询中,我们查找t1.related = t2.id
(中间两列)的匹配项。这对应于标有星号的行。但是,t.id = 1
没有匹配,因此我们需要包含此内容,但需要NULL
,因为LEFT JOIN
的含义是什么(不匹配仍会返回NULL
)。
+-------+-------+
| t1.id | t2.id |
+-------+-------+
| 1 | NULL | added because LEFT JOIN
| 2 | 1 | marked with * in table above
| 4 | 1 | marked with * in table above
+-------+-------+
在第二个查询中,我们查找t1.id = t2.related
(外部两列)的匹配项。这对应于标有加号的行。但是,t.id = 2
和t.id = 4
没有匹配,因此我们需要包含这些内容,但需要NULL
,因为LEFT JOIN
意味着什么(不匹配)返回NULL
)。
+-------+-------+
| t1.id | t2.id |
+-------+-------+
| 1 | 2 | marked with + in table above
| 1 | 4 | marked with + in table above
| 2 | NULL | added because LEFT JOIN
| 4 | NULL | added because LEFT JOIN
+-------+-------+
答案 1 :(得分:1)
第一次查询:t1.related = t2.id
t1 joined t2 id related | id related --------------+------------- 1 NULL | -- -- 2 1 | 1 NULL 3 1 | 1 NULL
内连接只会产生两行,但外连接也会保留第一行不匹配。
第二次查询:t1.id = t2.related
t1 joined t2 id related | id related --------------+------------- 1 NULL | 2 1 1 NULL | 3 1 2 1 | -- -- 3 1 | -- --
这里,内连接只会产生两行,但外连接也会保留两行不匹配的行。
答案 2 :(得分:0)
在第一种情况下,我们需要将值1,2,3与NULL
,1和1匹配。由于它是left join
,NULL
将保持不匹配,1将会与其他表格中的1匹配,因此有3条记录。
在第二种情况下,我们有值1,2,3。2和3没有匹配,将产生两行,但1有 2 匹配,并将导致另外2行,这是4行。
一般来说,有:
... LeftTable [LT] left join RightTable [RT] on [LT].[joinCol] = [RT].pjoinCol] ...
会像这样工作:
从LT.joinCol
获取所有值,尝试与RT.joinCol
中的值匹配。如果某个值在n
中匹配RT.joinCol
,则会产生n
行。如果该行没有匹配,它仍将导致一个未匹配的记录。
在第一种情况下,2个值有1个匹配=> 1 + 1 = 2
条记录。一个值没有匹配=> 1条记录,2 + 1 = 3
。
在你的第二种情况下,2个值没有匹配=>因此2条记录,一条值有2条匹配=> 2条记录,2 + 2 = 4
:)
答案 3 :(得分:0)
查看自联接的最佳方法是创建两个表,然后查看连接条件。
表t1
Id Related
1 null
2 1
4 1
表t2
Id Related
1 null
2 1
4 1
注意:左连接表示即使连接条件不匹配,左表中的所有内容也会出现。从右表中它将变为空。
首先查询: t1.related = t2.id; (列选择“t1.id,t2.id”)
1。)让我们从t1表中获取第一行,相关列具有空值。 null在t2表的id列中不匹配。因为它是左连接,所以行将来自t1表。
第一行:
t1_id t2_id
1 null
2.。)让我们从t1表中取第二行,相关列有1. 1在t2表的id列中有一个匹配。因此连接条件中有一行。
第二行:
t1_id t2_id
2 1
3.。)让我们从t1表中取第三行,相关列有1. 1在t2表的id列中有一个匹配。因此连接条件中有一行。
第三行:
t1_id t2_id
4 1
第二次查询 t1.id = t2.related(列选择“t1.id,t2.id”)
1。)让我们从t1表中获取第一行,id列为1. 1在t2表的相关列中有2行。所以选择了两行。
t1.id t2.id
1 2
1 4
2.。)让我们从t1表中获取第二行,id列为2. 2在t2表的相关列中有0行。但它左边的连接行将来自t1表。
t1.id t2.id
1 2
1 4
2 null
2。)让我们从t1表中获取第三行,id列为4. 4在t2表的相关列中有0行。但它左边的连接行将来自t1表。
t1.id t2.id
1 2
1 4
2 null
4 null
希望这会让你明白。
由于 ANKIT。
答案 4 :(得分:0)
LEFT JOIN返回左表中的所有元组,即使右表中没有匹配加右表的匹配值。
SELECT t1.id as t1_id, t1.related as t1_r, t2.id as t2_id, t2.related as t2_r
FROM mytable as t1
LEFT JOIN mytable as t2 ON t1.related = t2.id;
返回
t1_id t1_r t2_id t2_r
----------------------------
1 null null null
2 1 1 null
4 1 1 null
(1,null)t1的元组与t2中没有元组匹配, (2,1)t1的元组匹配t2的一个元组(1,null), 因此(4,1)因此结果为3行
在哪里
SELECT t1.id as t1_id, t1.related as t1_r, t2.id as t2_id, t2.related as t2_r
FROM test1 as t1
LEFT JOIN test1 as t2 ON t1.id = t2.related ;
返回
t1_id t1_r t2_id t2_r
-----------------------------
1 null 2 1
1 null 4 1
2 1 null null
4 1 null null
这里(1,null)的t1匹配t2(2,1)和(4,1)和(2,1)和(4,1)的两个元组没有元组匹配因此4行