لقد حدث أنني أجريت بعض المقابلات لموقف مبرمج الويب. أحد الأسئلة المطلوبة التي أطرحها هي كيف يختلف INNER JOIN عن LEFT JOIN.
في أغلب الأحيان ، يكون الجواب مثل هذا: "الصلة الداخلية تشبه تقاطع المجموعات ، أي فقط ما تبقى في كلا الجدولين ، والنقطة اليسرى هي عندما يظل الجدول الأيسر دون تغيير ، ويضاف تقاطع المجموعات من اليمين. جميع الخطوط الأخرى لاغية ". يحدث أيضًا أن يرسموا دوائر متقاطعة.
لقد سئمت من هذه الإجابات بتقاطعات مجموعات ودوائر لدرجة أنني توقفت عن تصحيح الأشخاص.
الحقيقة هي أن هذه الإجابة غير صحيحة بشكل عام. حسنا ، أو على الأقل ليست دقيقة.
دعونا نلقي نظرة على السبب ، وفي الوقت نفسه نلمس زوجين من التفاصيل الدقيقة للانضمام.
بادئ ذي بدء ، الجدول ليس كثيرًا على الإطلاق. حسب التعريف الرياضي ، في المجموعة جميع العناصر فريدة من نوعها ، لا تتكرر ، وفي الجداول في الحالة العامة هذا في الواقع ليس كذلك. المشكلة الثانية هي أن مصطلح "تقاطع" يخلط فقط.
( تحديث . في التعليقات هناك جدل ساخن حول نظرية المجموعات والتفرد. مثيرة جدا للاهتمام ، لقد تعلمت الكثير من الأشياء الجديدة ، شكرا)
الداخلية انضم
دعنا نعطي مثالاً على الفور.
لذلك ، دعونا ننشئ جدولين متطابقين مع عمود معرف واحد ، في كل من هذه الجداول سيكون هناك صفين بقيمة 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 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/