Какие типы соединений (JOIN) существуют в PostgreSQL и для чего используется каждый из них?

Ответ

В PostgreSQL, как и в большинстве реляционных СУБД, JOIN используется для объединения строк из двух или более таблиц на основе связанных столбцов. Вот основные типы:

  1. INNER JOIN (или просто JOIN)

    • Что делает: Возвращает только те строки, для которых найдено совпадение в обеих таблицах.
    • Когда использовать: Когда нужно получить данные, которые присутствуют в обеих таблицах. Например, получить список пользователей и их заказов (пользователи без заказов не попадут в выборку).
      SELECT users.name, orders.id
      FROM users
      INNER JOIN orders ON users.id = orders.user_id;
  2. LEFT JOIN (или LEFT OUTER JOIN)

    • Что делает: Возвращает все строки из левой таблицы и совпадающие строки из правой. Если совпадения в правой таблице нет, ее столбцы будут заполнены NULL.
    • Когда использовать: Когда нужно получить все записи из одной таблицы и дополнить их данными из другой, если они есть. Например, получить всех пользователей и их заказы (пользователи без заказов тоже попадут в выборку, но поля заказа будут NULL).
      SELECT users.name, orders.id
      FROM users
      LEFT JOIN orders ON users.id = orders.user_id;
  3. RIGHT JOIN (или RIGHT OUTER JOIN)

    • Что делает: Зеркальное отражение LEFT JOIN. Возвращает все строки из правой таблицы и совпадающие из левой. Если совпадения нет, столбцы левой таблицы будут NULL.
    • Когда использовать: Реже используется на практике, так как почти всегда можно переписать запрос через LEFT JOIN, поменяв таблицы местами, что часто делает его более читаемым.
      SELECT users.name, orders.id
      FROM users
      RIGHT JOIN orders ON users.id = orders.user_id;
  4. FULL OUTER JOIN

    • Что делает: Возвращает все строки из обеих таблиц. Если для строки из одной таблицы нет совпадения в другой, недостающие столбцы заполняются NULL.
    • Когда использовать: Когда нужно получить полный набор данных из двух таблиц, независимо от наличия совпадений. Например, для поиска расхождений в данных.
      SELECT * FROM table1
      FULL OUTER JOIN table2 ON table1.id = table2.id;
  5. CROSS JOIN

    • Что делает: Возвращает декартово произведение двух таблиц — каждая строка первой таблицы соединяется с каждой строкой второй. Условие ON не используется.
    • Когда использовать: Редко применяется на реальных данных. Может быть полезно для генерации тестовых данных или комбинаторных наборов.
      SELECT * FROM table1 CROSS JOIN table2;
  6. SELF JOIN (Техника, а не отдельный тип)

    • Что делает: Это не отдельный вид JOIN, а техника соединения таблицы с самой собой. Для этого таблице присваиваются разные псевдонимы (aliases).
    • Когда использовать: Когда в одной таблице есть иерархические или рекурсивные связи. Например, найти для каждого сотрудника его руководителя в таблице employees.
      SELECT e.name AS employee_name, m.name AS manager_name
      FROM employees e
      LEFT JOIN employees m ON e.manager_id = m.id;

Ответ 18+ 🔞

А, ну вот, опять про эти ваши джойны, ебать мои старые костыли! Слушай, щас как на пальцах разжуёшь, чтобы даже тот, кто SQL видит впервые, понял. Это ж не хуй с горы, тут логика есть.

Представь, что у тебя есть таблица users — это наши чуваки. И таблица orders — это их заказы, которые они наделали. Связь через user_id. Так вот, как их скрестить, чтобы не получилась каша?

INNER JOIN (или просто JOIN) Это как строгий бухгалтер, блядь. Берёт только тех, у кого всё по паспорту. То есть, только пользователей, у которых есть заказы, и только заказы, у которых есть пользователи. Кто без заказа — тот лох и нахуй не нужен. Вот так:

SELECT users.name, orders.id
FROM users
INNER JOIN orders ON users.id = orders.user_id;

Всё чётко, без лишних соплей.

LEFT JOIN (или LEFT OUTER JOIN) А вот это уже по-человечески. Он говорит: «Да похуй, есть заказ или нет — всех пользователей покажи!». Берёт ВСЕХ из левой таблицы (users), и если у чувака есть заказы — подтягивает их. А если нет — так и пишет: NULL, мол, пусто, блядь. Пользователь-то есть, а заказов — ноль.

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

Вот это чаще всего и нужно, ёпта.

RIGHT JOIN А это, блядь, такой левша-перевёртыш. Всё то же самое, что LEFT JOIN, но наоборот: берёт ВСЕ заказы из правой таблицы, и к ним подтягивает пользователей. Если заказ какой-то левый и пользователя к нему нет — будет NULL в имени. Но честно говоря, его почти не используют, потому что можно просто таблицы местами поменять и сделать LEFT JOIN — так понятнее, в рот меня чих-пых.

FULL OUTER JOIN Это уже полный пиздец, извини за выражение. Берёт ВСЁ И ОТОВСЮДУ. Всех пользователей и все заказы. Если что-то никуда не приклеилось — так и будет висеть NULL-ами. Нужно это редко, обычно для поиска дыр в данных: «А какой, сука, заказ висит без пользователя? И какой пользователь ни разу не заказал?».

SELECT * FROM table1
FULL OUTER JOIN table2 ON table1.id = table2.id;

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

SELECT * FROM table1 CROSS JOIN table2;

SELF JOIN А это не отдельный тип, а хитрая жопа, техника такая. Когда таблица соединяется сама с собой. Например, в таблице employees есть и работники, и их начальники, которые тоже записаны как работники. Чтобы вывести «Вася -> Петя (начальник)», надо сделать так:

SELECT e.name AS employee_name, m.name AS manager_name
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id;

Видишь? Одна и та же таблица, но под разными именами — e и m. И соединяем мы сотрудника (e) с его менеджером (m) через айдишник.

Вот и вся магия, блядь. Главное — понять, что откуда тянуть: всё из левой таблицы или только общее. А дальше — дело техники.