TGStat
TGStat
Type to search
Advanced channel search
  • flag English
    Site language
    flag Russian flag English flag Uzbek
  • Sign In
  • Catalog
    Channels and groups catalog Regional compilations Thematic compilations Платные каналы Search for channels
    Add a channel/group
  • Ratings
    Rating of channels Rating of groups Posts rating
    Ratings of brands and people
  • Analytics
  • Search by posts
  • Telegram monitoring
  • Promotion
    Advertising through Yandex Business Advertising in channels through TGStat Agency Advertising on TGStat.ru website
Дима SQL-ит 🧑‍💻 (Аналитика данных, AI)

20 Aug, 07:40

Open in Telegram Share Report

01:32
📝 Как работают JOIN в SQL — разбор на пальцах:

Разберём, откуда берутся дубли и почему порядок таблиц в join важен.
Условие: Две таблицы, связаны по ключу users.id = orders.user_id:

users
id name
1 Аня
2 Боря
3 Вика

orders
user_id sum
1 500
1 300
2 700
4 900


У Ани два заказа, у Бори один, у Вики заказов нет. А заказ на 900 — от юзера 4, которого в users нет.

1️⃣ INNER JOIN — только совпадения
Берём каждую строку слева и ищем ей пару справа. Нет пары — строки нет.

SELECT u.name, o.sum
FROM users u
JOIN orders o ON u.id = o.user_id;

Аня 500
Аня 300
Боря 700


Вика вылетела — у неё нет заказов. Заказ на 900 вылетел — у него нет юзера.

2️⃣ Откуда дубли
Аня в результате дважды. Строку слева никто не копировал — просто справа ей нашлось два совпадения:
1 строка × 2 совпадения = 2 строки.

Отсюда классическая ошибка: COUNT(*) после JOIN считает не юзеров, а пары. Считать надо COUNT(DISTINCT u.id).

3️⃣ LEFT JOIN — все слева
Оставляем каждую строку левой таблицы. Нет пары — правая часть заполняется NULL.

SELECT u.name, o.sum
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;

Аня 500
Аня 300
Боря 700
Вика NULL -- осталась, но пустая


4️⃣ Порядок таблиц решает
Тот же LEFT JOIN, то же ON. Меняем только одно — какая таблица стоит слева:

SELECT u.name, o.sum
FROM orders o
LEFT JOIN users u ON o.user_id = u.id;

Аня 500
Аня 300
Боря 700
NULL 900 -- заказ без юзера остался


Вики больше нет. Бережём мы теперь orders, а не users.
u LEFT o ≠ o LEFT u.

5️⃣ RIGHT JOIN — то же, но без перестановки
RIGHT держит все строки правой таблицы:

SELECT u.name, o.sum
FROM users u
RIGHT JOIN orders o ON u.id = o.user_id;


Результат тот же, что в шаге 4: o LEFT u = u RIGHT o. RIGHT почти не пишут — переставить таблицы и оставить LEFT читается проще.

6️⃣ FULL OUTER JOIN — не теряем никого
Всё с обеих сторон, чего нет — NULL:

Аня 500
Аня 300
Боря 700
Вика NULL -- юзер без заказов
NULL 900 -- заказ без юзера


FULL = LEFT + RIGHT. Удобно для сверки двух источников: сразу видно пропуски с обеих сторон.

7️⃣ CROSS JOIN — каждая с каждой
Единственный джойн без ON. 2 юзера × 2 промокода = 4 строки:

SELECT u.name, p.code
FROM users u
CROSS JOIN promo p;

Аня SALE10
Аня SALE20
Боря SALE10
Боря SALE20


Это декартово произведение: N × M строк. Нужен редко — например, разложить каждого юзера по всем дням календаря.

8️⃣ Цепочка из трёх таблиц
users → orders → payments, всюду LEFT:

SELECT u.name, o.id AS order_id, p.sum AS paid
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
LEFT JOIN payments p ON p.order_id = o.id;

Аня 10 500
Боря 20 NULL
Вика NULL NULL


3 строки — все юзеры на месте.

9️⃣ Ловушка: стартовали не с той таблицы
Джойны те же, LEFT. Меняем только стартовую таблицу:

FROM payments p
LEFT JOIN orders o ON o.id = p.order_id
LEFT JOIN users u ON u.id = o.user_id;

Аня 10 500


Одна строка.
Боря и Вика в набор даже не попали — платежа-то у них нет, а LEFT бережёт только то, что уже слева.
Стартовая таблица задаёт максимум строк: дальше их можно только размножить или отфильтровать, но не добавить новых.

🔟 Ловушка: INNER после LEFT
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
JOIN payments p ON p.order_id = o.id; -- обычный JOIN = INNER

Аня 10 500


LEFT честно донёс Борю с NULL и Вику с NULL.
А следующий INNER выкинул все строки без пары

Шпаргалка:
INNER — только совпадения
LEFT — все слева + совпадения
RIGHT — все справа + совпадения
FULL — всё с обеих сторон
CROSS — каждая с каждой (N × M)

Итог: 🤩  

❓  Все ли теперь стало понятно в теме join? Пишите в комментариях!
✔️ Подпишитесь на канал, чтобы не пропустить следующие хаки.


🚬 Вопросы, обучение, консультации:  Написать в ЛС | mentor.dima-sqlit.ru 


@dima_sqlit

1.4k 1 26 17 23
Catalog
Channels and groups catalog Channels compilations Search for channels Add a channel/group
Ratings
Rating of Telegram channels Rating of Telegram groups Posts rating Ratings of brands and people
API
API statistics Search API of posts API Callback
Our channels
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Read
Академия TGStat Telegram Research 2019 Telegram Research 2021 Telegram Research 2023
Contacts
Справочный центр Support Email Jobs
Miscellaneous
Terms and conditions Privacy policy Public offer
Our bots
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot