Короткий ответ
Запрос использует LEFT JOIN, но добавляет условие на колонку правой таблицы в WHERE, что фактически превращает его в INNER JOIN — автор хотел получить всех клиентов, включая тех без заказов, но получит только клиентов с хотя бы одним заказом на сумму больше 100.
Как это работает подробнее
Условие WHERE применяется после JOIN к объединённому набору строк; для клиента без заказов orders.amount будет NULL, а сравнение NULL > 100 даёт UNKNOWN, такая строка отбрасывается так же, как FALSE.
Пример кода
example.sql
-- Исходный запрос с ошибкой:
SELECT c.id, c.name, o.amount
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.amount > 100;
-- Исправленный вариант, сохраняющий всех клиентов:
SELECT c.id, c.name, o.amount
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id AND o.amount > 100;Что использовать на практике
- Практика. Чтобы сохранить семантику LEFT JOIN при фильтрации по правой таблице, условие на amount нужно переносить в сам ON, либо использовать (orders.amount > 100 OR orders.id IS NULL), в зависимости от того, что требуется получить.
Подводные камни
- Ошибка. Эту ошибку часто не замечают в code review, потому что запрос синтаксически корректен и возвращает правдоподобные данные — проверять такие случаи нужно тестом с заведомо «пустым» клиентом.