Aconteceu que eu conduzi várias entrevistas para a posição de programador da web. Uma das perguntas necessárias que faço é como o INNER JOIN difere do LEFT JOIN.
A resposta mais comum é algo assim: "junção interna é como a interseção de conjuntos, ou seja, apenas o que resta nas duas tabelas permanece, e junção esquerda é quando a tabela esquerda permanece inalterada e a interseção de conjuntos é adicionada da direita. todas as outras linhas são anexadas com nulo ". Também acontece que eles desenham círculos que se cruzam.
Eu estava tão cansado dessas respostas com interseções de séries e círculos que até parei de corrigir as pessoas.
O fato é que essa resposta geralmente está incorreta. Bem, ou pelo menos não preciso.
Vamos ver o porquê e, ao mesmo tempo, abordar mais algumas sutilezas de junções.
Primeiro de tudo, uma mesa não é muita coisa. Por definição matemática, no conjunto todos os elementos são únicos, não são repetidos e, nas tabelas, no caso geral, isso não é verdade. O segundo problema é que o termo "interseção" apenas confunde.
( Atualização . Nos comentários, há um acalorado debate sobre teoria dos conjuntos e singularidade. Muito interessante, eu aprendi muitas coisas novas, obrigado)
INNER JOIN
Vamos dar um exemplo imediatamente.
Portanto, criaremos duas tabelas idênticas com uma coluna de id, em cada uma dessas tabelas haverá duas linhas com o valor 1 e outra coisa.
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/