DBAtlas · Атлас эксплуатации баз данных

Типы JOIN (INNER/LEFT/RIGHT/FULL/CROSS)

Oracle

-- INNER: matching rows
SELECT m.name, s.amount
FROM customer m JOIN orders s ON m.id = s.customer_id;
-- LEFT: customers without orders are included too
SELECT m.name, s.amount
FROM customer m LEFT JOIN orders s ON m.id = s.customer_id;
-- CROSS: Cartesian product
SELECT r.name, u.name FROM color r CROSS JOIN product u;

JOIN объединяет две таблицы по заданному условию. INNER возвращает только совпадения; LEFT/RIGHT возвращают все строки одной стороны (NULL при отсутствии совпадения); FULL возвращает строки обеих сторон; CROSS — все комбинации. Помимо стандартных ANSI JOIN, Oracle поддерживает и старый синтаксис внешнего соединения (+).

PostgreSQL

SELECT m.name, s.amount
FROM customer m INNER JOIN orders s ON m.id = s.customer_id;

SELECT m.name, s.amount
FROM customer m LEFT JOIN orders s ON m.id = s.customer_id;

SELECT m.name, s.amount
FROM customer m FULL OUTER JOIN orders s ON m.id = s.customer_id;

PostgreSQL полностью поддерживает все стандартные типы JOIN (INNER, LEFT/RIGHT/FULL OUTER, CROSS). USING(my_column) — сокращение для одноимённых столбцов, а NATURAL JOIN автоматически соединяет по всем одноимённым столбцам (используйте осторожно).

MySQL

SELECT m.name, s.amount
FROM customer m INNER JOIN orders s ON m.id = s.customer_id;

SELECT m.name, s.amount
FROM customer m LEFT JOIN orders s ON m.id = s.customer_id;

-- MySQL has no FULL OUTER JOIN:
SELECT m.name, s.amount FROM customer m LEFT JOIN orders s ON m.id = s.customer_id
UNION
SELECT m.name, s.amount FROM customer m RIGHT JOIN orders s ON m.id = s.customer_id;

MySQL/MariaDB поддерживают INNER, LEFT, RIGHT и CROSS JOIN, но не предлагают FULL OUTER JOIN напрямую; он эмулируется объединением результатов LEFT и RIGHT через UNION. Старое соединение через запятую даёт декартово произведение и должно ограничиваться через ON/WHERE.

SQL Server

SELECT m.name, s.amount
FROM customer m INNER JOIN orders s ON m.id = s.customer_id;

SELECT m.name, s.amount
FROM customer m LEFT JOIN orders s ON m.id = s.customer_id;

SELECT m.name, s.amount
FROM customer m FULL OUTER JOIN orders s ON m.id = s.customer_id;

SQL Server поддерживает все стандартные типы JOIN. Старые операторы внешнего соединения *= / =* удалены; нужно использовать синтаксис ANSI JOIN. APPLY (CROSS/OUTER APPLY) — дополнительная форма соединения для построчных коррелированных подзапросов.

MongoDB

// Closest equivalent: $lookup (left outer join)
db.customer.aggregate([
  { $lookup: {
      from: "orders",
      localField: "id",
      foreignField: "customer_id",
      as: "orders"
  } }
])

В MongoDB нет классического JOIN; этап агрегации $lookup получает совпадающие документы из другой коллекции в виде массива (похоже на left outer join). Для результата как у INNER отфильтруйте пустые массивы через $match, а массив разверните в строки через $unwind.

Redis

# Not applicable: Redis has no tables or JOINs.

Redis не предлагает реляционных соединений; данные обычно денормализуются, либо связи строятся на стороне клиента чтением нескольких ключей. Для ограниченных запросов, похожих на соединения, можно использовать RediSearch (FT.AGGREGATE); поддержка модуля RedisGraph прекращена в 2023.

Elasticsearch

# Not applicable: there is no general JOIN in a distributed design.
# Limited options: nested, parent/child (join field),
# terms lookup. Data is usually denormalized at indexing time.

Из-за распределённой архитектуры Elasticsearch не предлагает произвольных JOIN между таблицами. Для ограниченных связей есть тип поля 'nested' в пределах одного индекса и тип поля 'join' (parent/child) на одном шарде. Самое распространённое решение — денормализация данных при индексации.

Открыть в DBAtlas →