← Назад к вопросам

Что такое left join в SQL?

2.3 Middle🔥 161 комментариев
#Базы данных и SQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

LEFT JOIN в SQL

LEFT JOIN (левое внешнее объединение) — это операция, которая объединяет две таблицы таким образом, что в результат включаются ВСЕ записи из левой таблицы, и только совпадающие записи из правой таблицы. Для несовпадающих записей из правой таблицы используются значения NULL.

Синтаксис

SELECT *
FROM table1
LEFT JOIN table2 ON table1.id = table2.id;

Альтернативное название: LEFT OUTER JOIN (результат идентичен).

Принцип работы

LEFT JOIN сначала берёт ВСЕ строки из левой таблицы, затем для каждой ищет совпадающие строки в правой таблице:

  • Если совпадение найдено — объединяет строки
  • Если совпадения нет — берёт строку из левой таблицы с NULL для всех столбцов правой таблицы

Пример со стандартной схемой

Допустим, у нас есть два набора данных:

Таблица users:

idname
1Иван
2Мария
3Петр

Таблица orders:

iduser_idamount
11100
21200
32150
SELECT 
    users.id,
    users.name,
    orders.id AS order_id,
    orders.amount
FROM users
LEFT JOIN orders ON users.id = orders.user_id;

Результат:

idnameorder_idamount
1Иван1100
1Иван2200
2Мария3150
3ПетрNULLNULL

Замечу, что Петр включён в результат, хотя у него нет заказов!

LEFT JOIN в Java (JPA/Hibernate)

В Java приложениях LEFT JOIN часто используется при работе с ORM фреймворками:

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;

public interface UserRepository extends CrudRepository<User, Long> {
    // LEFT JOIN через JPQL
    @Query("SELECT u FROM User u LEFT JOIN u.orders o")
    List<User> findAllWithOrders();
    
    // С условием WHERE
    @Query("SELECT u FROM User u LEFT JOIN u.orders o WHERE o.amount > :minAmount")
    List<User> findUsersWithHighOrders(@Param("minAmount") BigDecimal minAmount);
}
// Сущности
@Entity
@Table(name = "users")
public class User {
    @Id
    private Long id;
    
    private String name;
    
    @OneToMany(mappedBy = "user")
    private List<Order> orders = new ArrayList<>();
}

@Entity
@Table(name = "orders")
public class Order {
    @Id
    private Long id;
    
    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;
    
    private BigDecimal amount;
}

LEFT JOIN vs INNER JOIN

INNER JOIN — только совпадающие строки из обеих таблиц:

-- Только пользователей с заказами
SELECT users.name, orders.amount
FROM users
INNER JOIN orders ON users.id = orders.user_id;

-- Результат: только Иван и Мария (Петр исключен)

LEFT JOIN — ВСЕ пользователи, даже без заказов:

-- Всех пользователей, даже без заказов
SELECT users.name, orders.amount
FROM users
LEFT JOIN orders ON users.id = orders.user_id;

-- Результат: Иван, Мария И Петр

Несколько LEFT JOIN

Можно объединять несколько таблиц:

SELECT 
    users.name,
    orders.amount,
    payments.status
FROM users
LEFT JOIN orders ON users.id = orders.user_id
LEFT JOIN payments ON orders.id = payments.order_id;

Фильтрация с LEFT JOIN

Важно: условия в WHERE и ON работают по-разному:

-- Вариант 1: условие в ON
-- Петр будет в результате с NULL
SELECT users.name, orders.amount
FROM users
LEFT JOIN orders ON users.id = orders.user_id AND orders.amount > 100;

-- Вариант 2: условие в WHERE
-- Петр НЕ будет в результате (отфильтрован)
SELECT users.name, orders.amount
FROM users
LEFT JOIN orders ON users.id = orders.user_id
WHERE orders.amount > 100;

Производительность

Когда использовать LEFT JOIN:

  • Нужны ВСЕ записи из левой таблицы
  • Некоторые записи могут не иметь связь с правой таблицей

Не забывать про индексы:

-- Создай индекс на столбец связи
CREATE INDEX idx_orders_user_id ON orders(user_id);

Распространённые ошибки

-- ❌ НЕПРАВИЛЬНО: WHERE фильтрует NULL
SELECT *
FROM users
LEFT JOIN orders ON users.id = orders.user_id
WHERE orders.user_id IS NOT NULL;  -- Это делает LEFT JOIN обычным JOIN!

-- ✅ ПРАВИЛЬНО: условие в ON
SELECT *
FROM users
LEFT JOIN orders ON users.id = orders.user_id
AND orders.user_id IS NOT NULL;

Заключение

LEFT JOIN — один из самых часто используемых инструментов SQL. Он критичен для:

  • Отчётов с опциональными данными
  • Поиска записей БЕЗ связанных данных
  • Анализа полноты информации

Понимание разницы между LEFT JOIN и INNER JOIN essential для написания корректных запросов.