結合の理解が壊れています。 これは間違いなく円の交差点ではありません

そのため、私はWebプログラマーの地位についてかなりの数のインタビューを行いました。 私が尋ねる必須の質問の1つは、INNER JOINとLEFT JOINの違いです。







最も一般的な答えは次のようなものです。「内部結合はセットの共通部分に似ています。つまり、両方のテーブルに残っているものだけが残ります。他のすべての行はnull "が追加されます。 また、交差する円を描くこともあります。







セットとサークルの交差点でのこれらの答えにうんざりしていたので、人々を修正することさえ止めました。







事実は、この答えが一般的に間違っているということです。 まあ、または少なくとも正確ではありません。







その理由を見てみましょう。同時に、いくつかの微妙な結合に触れてみましょう。







まず、テーブルは多数ではありません。 数学的な定義では、セット内のすべての要素は一意であり、繰り返されません。一般的な場合のテーブルでは、実際にはそうではありません。 2番目の問題は、「交差点」という用語が混乱するだけであることです。







更新 。コメントでは、集合論と一意性についての激しい議論があります。非常に興味深い、私は多くの新しいことを学びました、ありがとう)







インナージョイン



すぐに例を挙げましょう。







したがって、1つのid列を持つ2つの同一のテーブルを作成しましょう。これらの各テーブルには、1の値と2つの値を持つ2つの行があります。







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 JOIN



condition



. -, , , - .







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/








All Articles