对联接的理解被打破了。 老实说,这绝对不是圈子的交集

碰巧我针对Web程序员的职位进行了很多采访。 我要问的必要问题之一是INNER JOIN与LEFT JOIN有何不同。


通常,答案是这样的:“内部联接就像集合的交集,也就是说,只有两个表中剩下的都保留,而左联接是当左边的表保持不变时,集合的交集从右边的表中添加。其他所有行均附加null。 也有可能他们画出相交的圆。


我对集合和圆圈的交集感到厌倦,以至于我什至不再纠正人。


事实是这个答案通常是不正确的。 好吧,或者至少不准确。


让我们看一下原因,同时涉及到join-s的更多细微差别。


首先,一张桌子根本不是很多。 根据数学定义,集合中的所有元素都是唯一的,不会重复,在一般情况下,在表中实际上并非如此。 第二个麻烦是术语“交叉点”只会混淆。


更新 。在评论中,关于集合论和唯一性的争论非常激烈。非常有趣,我学到了很多新东西,谢谢)


内联接


让我们立即举一个例子。


因此,我们将创建两个具有一个id列的相同表,在这些表中的每个表中将有两行,其值为1或其他值。


INSERT INTO table1
(id)
VALUES
(1),
(1)
(3);

INSERT INTO table2
(id)
VALUES
(1),
(1),
(2);

, , ,


SELECT *
FROM table1
   INNER JOIN table2
      ON table1.id = table2.id;

" ", " ", .



:


| id  | id  |
| --- | --- |
| 1   | 1   |
| 1   | 1   |
| 1   | 1   |
| 1   | 1   |


??


, CROSS JOIN. - .


CROSS JOIN — . , , 3 , — 2:


select * from t1;

 id 
----
  1
  2
  3

select * from t2;

 id 
----
  4
  5

CROSS JOIN 6 .


select * 
from t1
   cross join t2; 

 id | id 
----+----
  1 |  4
  1 |  5
  2 |  4
  2 |  5
  3 |  4
  3 |  5

, .


t1 INNER JOIN t2 ON condition

— , ,


t1 CROSS JOIN t2  WHERE condition

.. INNER JOINcondition. -, , , - .


disclaimer: inner join cross join , , , : . .


LEFT JOIN


, , null, , .


, :


insert into t1 
(id)
values
(1),
(1),
(3);

insert into t2
(id)
values
(1),
(1),
(4),
(5);

LEFT JOIN:


SELECT * 
FROM t1
   LEFT JOIN t2 
       ON t1.id = t2.id;

5 , , .


| id  | id  |
| --- | --- |
| 1   | 1   |
| 1   | 1   |
| 1   | 1   |
| 1   | 1   |
| 3   |     |

, LEFT JOIN — INNER JOIN (.. , - ), , .


LEFT JOIN :


SELECT * 
FROM t1 
   CROSS JOIN t2
   WHERE t1.id = t2.id

UNION ALL

SELECT t1.id, null
   FROM t1
   WHERE NOT EXISTS (
        SELECT
        FROM t2
        WHERE t2.id = t1.id
   )

, , , ..


ON


, 99% , ON id id . .


, users_stats, ip .


SELECT s.id, c.city 
FROM users_stats AS s
    JOIN cities_ip_ranges AS c
        ON c.ip_range && s.ip

&& — (. ip4r)


ON true, CROSS JOIN


"table1 JOIN table2 ON true"  == "table1 CROSS JOIN table2"


, join- . " ". , join- . .. - - php.


, , .


, , . , . , , , .


O(n!), n — . , , , . CTE; , , , , , .


, . , , 'LEFT JOIN… WHERE… IS NULL', EXISTS. , .



, . , , "".


, , , . — , , . " ". .


Update. : https://habr.com/ru/post/450528/

Source: https://habr.com/ru/post/zh-CN448072/


All Articles