Какие существуют виды JOIN-операций в SQL и каково их назначение?

Ответ

JOIN-операции в SQL используются для объединения строк из двух или более таблиц на основе связанных между ними столбцов. Основные виды JOIN:

  1. INNER JOIN (Внутреннее соединение)

    • Назначение: Возвращает только те строки, для которых найдено совпадение в обеих таблицах. Это аналог пересечения множеств.
    • Пример: SELECT * FROM A INNER JOIN B ON A.id = B.id;
  2. LEFT JOIN (Левое внешнее соединение)

    • Назначение: Возвращает все строки из левой таблицы (A) и совпадающие строки из правой (B). Если совпадения для строки из левой таблицы нет, поля правой таблицы будут заполнены NULL.
    • Пример: SELECT * FROM A LEFT JOIN B ON A.id = B.id;
  3. RIGHT JOIN (Правое внешнее соединение)

    • Назначение: Работает зеркально LEFT JOIN. Возвращает все строки из правой таблицы (B) и совпадающие из левой (A). Если совпадения нет, поля левой таблицы будут NULL.
    • Пример: SELECT * FROM A RIGHT JOIN B ON A.id = B.id;
  4. FULL OUTER JOIN (Полное внешнее соединение)

    • Назначение: Возвращает все строки из обеих таблиц. Если для строки из одной таблицы нет совпадения в другой, недостающие поля заполняются NULL. Это аналог объединения множеств.
    • Пример: SELECT * FROM A FULL OUTER JOIN B ON A.id = B.id;
  5. CROSS JOIN (Перекрестное соединение)

    • Назначение: Возвращает декартово произведение двух таблиц — каждая строка из первой таблицы соединяется с каждой строкой из второй. Условие ON не используется.
    • Пример: SELECT * FROM A CROSS JOIN B;
  6. SELF JOIN (Соединение таблицы с собой)

    • Назначение: Это не отдельный вид JOIN, а техника, при которой таблица соединяется сама с собой с использованием псевдонимов (aliases). Используется для работы с иерархическими данными (например, 'сотрудник' и его 'менеджер' в одной таблице).
    • Пример: SELECT e.name, m.name FROM employees e JOIN employees m ON e.manager_id = m.id;

В Go для выполнения этих запросов используется пакет database/sql или ORM-библиотеки (например, GORM, sqlx), которые позволяют конструировать и выполнять стандартные SQL-запросы.

Ответ 18+ 🔞

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

INNER JOIN — это как самый честный мужик. Берёт таблицу А, берёт таблицу Б, и говорит: «Дайте мне только то, что есть в обоих местах, а остальное нахуй не нужно». Если у тебя в одной таблице запись есть, а в другой — нет, её просто выкинут, как пустой окурок. Примерно так:

SELECT * FROM A INNER JOIN B ON A.id = B.id;

LEFT JOIN — это уже поинтереснее. Он говорит: «Левую таблицу я беру целиком, всю, до последней строчки. А из правой — только то, что подходит. Если не подходит — ну и хуй с ним, поставлю NULL». То есть левая таблица как бы главная, её не обидят.

SELECT * FROM A LEFT JOIN B ON A.id = B.id;

RIGHT JOIN — это то же самое, только наоборот. Правая таблица — царица, её не трогаем, а левую подтягиваем по остаточному принципу. Но честно говоря, его почти не используют, потому что можно просто таблицы местами поменять и LEFT сделать — и всем понятнее.

SELECT * FROM A RIGHT JOIN B ON A.id = B.id;

FULL OUTER JOIN — это вообще ёперный театр. Он берёт ВСЁ из обеих таблиц. Было в левой — пожалуйста. Было в правой — на здоровье. Где совпало — склеил. Где нет — поставил NULL. Полный бардак, но иногда нужный.

SELECT * FROM A FULL OUTER JOIN B ON A.id = B.id;

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

SELECT * FROM A CROSS JOIN B;

SELF JOIN — звучит умно, а на деле — просто таблица сама с собой целуется. Ну, типа, у тебя в одной таблице и работники, и их начальники. Чтобы найти, кто кем руководит, ты эту таблицу клонируешь под разными именами и соединяешь саму с собой. Хитро, да?

SELECT e.name, m.name FROM employees e JOIN employees m ON e.manager_id = m.id;

А в Go, если что, это всё через стандартный database/sql делается, или через эти ваши ORM вроде GORM. Пишешь тот же SQL-запрос, выполняешь — и всё, блядь, работает. Главное — не перепутай, где LEFT, а где INNER, а то вместо всех данных получишь хуй с горы.