Какие виды JOIN в SQL вы знаете?

Ответ

В SQL существует несколько типов JOIN для объединения данных из двух и более таблиц.

Основные виды JOIN:

  1. INNER JOIN — возвращает только строки, для которых есть совпадение в обеих таблицах по условию.

    SELECT *
    FROM orders
    INNER JOIN customers ON orders.customer_id = customers.id;
  2. LEFT (OUTER) JOIN — возвращает все строки из левой таблицы и соответствующие строки из правой. При отсутствии совпадения в правой таблице возвращаются NULL.

    SELECT customers.name, orders.order_date
    FROM customers
    LEFT JOIN orders ON customers.id = orders.customer_id;
  3. RIGHT (OUTER) JOIN — противоположность LEFT JOIN: возвращает все строки из правой таблицы и соответствующие строки из левой.

  4. FULL (OUTER) JOIN — возвращает все строки из обеих таблиц, объединяя результаты LEFT и RIGHT JOIN. Отсутствующие совпадения заполняются NULL.

  5. CROSS JOIN — возвращает декартово произведение строк обеих таблиц (все возможные комбинации).

    SELECT *
    FROM sizes
    CROSS JOIN colors;
  6. SELF JOIN — соединение таблицы с самой собой, часто используется для иерархических данных (например, сотрудник -> менеджер).

    SELECT e1.name AS employee, e2.name AS manager
    FROM employees e1
    LEFT JOIN employees e2 ON e1.manager_id = e2.id;
  7. NATURAL JOIN — автоматически соединяет таблицы по столбцам с одинаковыми именами. На практике используется редко из-за неявного поведения, которое может привести к ошибкам.

Ответ 18+ 🔞

Давай разберем эту всю хуйню с JOIN'ами, а то народ постоянно в них путается, как мартышлюшка в унитазе. Ситуация проще, чем кажется, если не усложнять.

Представь, что у тебя есть две таблицы. Одна — список клиентов, другая — список заказов. И тебе надо их как-то склеить. Вот тут и начинается ёперный театр.

INNER JOIN — это как самый честный, но строгий мужик. Он тебе вернёт только те записи, где нашлось полное совпадение. Есть клиент и у него есть заказ? Отлично, пара готова. Нет заказа у клиента? Иди нахуй, не вижу тебя. Клиент есть, а заказа в таблице нет? Тоже пошёл вон. Только взаимность, только хардкор. Доверия ебать ноль к пропускам.

SELECT *
FROM orders
INNER JOIN customers ON orders.customer_id = customers.id;

LEFT JOIN — это уже хитрая жопа. Он говорит: «Всё, чувак, левая таблица у нас главная». Берёт ВСЕХ клиентов из левой таблицы, и тащит их заказы из правой. Нашёл заказ — молодца, приклеил. Не нашёл — да похуй, всё равно клиента выведем, просто там, где заказ, будет NULL. То есть клиент-то есть, а заказов у него нихуя. Это полезно, чтобы увидеть всех, даже самых бесполезных.

SELECT customers.name, orders.order_date
FROM customers
LEFT JOIN orders ON customers.id = orders.customer_id;

RIGHT JOIN — это та же самая хуйня, только наоборот. Теперь правая таблица царица бала. Всё из правой, и по возможности из левой. Используется реже, потому что обычно можно просто таблицы местами поменять и сделать LEFT JOIN.

FULL OUTER JOIN — это уже полный пиздец и бардак. Он берёт ВСЁ И ОТОВСЮДУ. Всех клиентов и все заказы. Где нашлось совпадение — склеил. Где клиент без заказа — вывел с NULL. Где заказ без клиента (странная ситуация, но бывает) — тоже вывел. Полная картина, хоть и с дырами. В MySQL его нет нативно, но можно эмулировать.

CROSS JOIN — это просто ебать-копать, декартово произведение. Берёт каждую строчку из первой таблицы и соединяет с КАЖДОЙ строчкой из второй. Если в первой таблице 10 строк, а во второй 20, получишь 200 строк. Овердохуища комбинаций. Полезно для генерации всех вариантов, например, размеров и цветов.

SELECT *
FROM sizes
CROSS JOIN colors;

SELF JOIN — звучит умно, а на деле — просто таблица соединяется сама с собой. Как будто ты сам с собой разговариваешь. Нужно, когда данные иерархические: например, в таблице employees есть столбец manager_id, который ссылается на id другого сотрудника в ЭТОЙ ЖЕ таблице. Чтобы вывести имя сотрудника и имя его начальника, приходится делать SELF JOIN.

SELECT e1.name AS employee, e2.name AS manager
FROM employees e1
LEFT JOIN employees e2 ON e1.manager_id = e2.id;

NATURAL JOIN — вот это, блядь, самая опасная штука. Он автоматически соединяет таблицы по столбцам с ОДИНАКОВЫМИ ИМЕНАМИ. Кажется, удобно? Ага, щас. Представь, что в обеих таблицах есть столбец created_at. Он возьмёт и соединит по нему, хотя тебе это вообще не нужно. Получится полная дичь. Поэтому его все боятся как огня и используют крайне редко. Сам от такого джойна охуевал не раз.

Вот и вся магия. Главное — понять, что тебе нужно: только совпадения (INNER), все из одной таблицы плюс что нашлось из другой (LEFT/RIGHT), или полный разгул (FULL/CROSS). А остальное — уже технические детали.