SQL INNER JOIN: объединение строк из двух таблиц
В SQL при использовании INNER JOIN вы получаете только те строки, где условие соединения совпадает в обеих таблицах. Используйте его, чтобы объединять связанные данные — например, связывать записи со значениями из справочников — когда строки без совпадения нужно исключить из результата. Поскольку предикат соединения должен выполняться с обеих сторон, любая строка с NULL в ключе соединения или без соответствующей пары автоматически отфильтровывается.
Пример SQL INNER JOIN Для Объединения Связанных Таблиц
Вывод:
Результат появится здесь...
Вывод:
+----------+-------------+
| employee | department |
+----------+-------------+
| Alma | Разработка |
| Ben | Разработка |
| Cara | Продажи |
+----------+-------------+
3 row(s)
Как Работает Этот Пример
departmentsхранит три отдела;employeesхранит четырех сотрудников, у каждого есть внешний ключdept_id. У Dan значениеdept_idравно NULL.INNER JOIN departments d ON d.id = e.dept_idсопоставляет каждую строку сотрудника со строкой отдела, гдеidотдела равенdept_idсотрудника. Сохраняются только пары, где совпадение есть с обеих сторон.- У Dan
dept_id = NULL. Оператор=возвращает unknown, если один из операндов равен NULL, поэтому Dan не совпадает ни с одним отделом и исключается. - В отделе HR (id 3) нет сотрудников, которые на него ссылаются, поэтому он тоже не появляется: INNER JOIN отбрасывает несовпавшие строки с обеих сторон.
Что Такое SQL INNER JOIN?
INNER JOIN возвращает пересечение двух таблиц по предикату соединения. Логически он сохраняет только те пары строк, где условие ON вычисляется в true. Физическое выполнение зависит от движка и формы данных (nested loops, hash join, merge join), но результирующий набор всегда содержит только совпавшие строки.
INNER JOIN vs LEFT JOIN
| INNER JOIN | LEFT JOIN |
|---|---|
| Возвращает только совпавшие строки из обеих таблиц | Возвращает все строки из левой таблицы и подставляет NULL там, где совпадения нет |
| Несовпавшие строки молча отбрасываются | Несовпавшие строки слева сохраняются, а правые столбцы заполняются NULL |
| Используется, когда отсутствие совпадения означает некорректные данные | Используется, когда нужно видеть все записи левой стороны независимо от совпадений |
Правило: выбирайте INNER JOIN, когда каждая строка результата должна содержать корректные данные из обеих таблиц. Переключайтесь на LEFT JOIN, когда нужно сохранять строки даже без совпадения справа.
Частые Ошибки С SQL INNER JOIN
Отсутствующий или всегда истинный предикат соединения
Пропуск ON (или условие, которое всегда истинно) создает декартово произведение: каждый сотрудник соединяется с каждым отделом.
-- Неправильно: декартово произведение (12 строк из 4 × 3)
SELECT * FROM employees, departments;
-- Правильно: явный предикат соединения
SELECT * FROM employees e
INNER JOIN departments d ON d.id = e.dept_id;
Неуникальные ключи соединения вызывают мультипликацию строк
INNER JOIN возвращает одну строку результата для каждой совпавшей пары. Если вы соединяете таблицу, где ключ не уникален, одна строка слева может совпасть с несколькими строками справа и умножить результат.
INNER JOIN vs EXISTS
Используйте INNER JOIN, когда в выводе нужны столбцы из обеих таблиц. Используйте EXISTS, когда нужно только отфильтровать строки по факту наличия связанной строки. EXISTS также предотвращает мультипликацию строк, если подзапрос может вернуть несколько совпадений, а планировщик запроса часто может остановиться после первого совпадения.
-- EXISTS: одна строка на сотрудника, у которого есть подходящий отдел
SELECT e.name FROM employees e
WHERE EXISTS (SELECT 1 FROM departments d WHERE d.id = e.dept_id);
Заметки О Производительности
Индексируйте столбцы, которые участвуют в предикате соединения (dept_id и departments.id в этом примере). Без индекса движок может многократно сканировать внутреннюю таблицу. Для больших таблиц проверяйте план через EXPLAIN QUERY PLAN: вместо SCAN лучше видеть USING INDEX или SEARCH.