了解LEFT JOIN中匹配行的数量

时间:2018-01-30 09:30:28

标签: sql left-join self-join

这是我的表结构: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" 在后​​台如何运作?

5 个答案:

答案 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 = 2t.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 joinNULL将保持不匹配,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行