SQL Server поддерживает несколько типов соединений, каждый из которых имеет свои особенности и сценарии применения. Рассмотрим их подробно.
Основные типы соединений
1. INNER JOIN
SELECT a.*, b.*
FROM TableA a
INNER JOIN TableB b ON a.key = b.key;
- Возвращает только совпадающие строки из обеих таблиц
- Самый быстрый тип соединения
- Используется по умолчанию, когда пишется просто JOIN
2. LEFT OUTER JOIN
SELECT a.*, b.*
FROM TableA a
LEFT OUTER JOIN TableB b ON a.key = b.key;
- Возвращает все строки из левой таблицы (TableA)
- Добавляет NULL для несовпадающих строк правой таблицы
- Часто используется для анализа "отсутствующих" данных
3. RIGHT OUTER JOIN
SELECT a.*, b.*
FROM TableA a
RIGHT OUTER JOIN TableB b ON a.key = b.key;
- Возвращает все строки из правой таблицы (TableB)
- Добавляет NULL для несовпадающих строк левой таблицы
- Менее популярен, чем LEFT JOIN (можно переписать)
4. FULL OUTER JOIN
SELECT a.*, b.*
FROM TableA a
FULL OUTER JOIN TableB b ON a.key = b.key;
- Возвращает все строки из обеих таблиц
- Добавляет NULL где нет совпадений
- Ресурсоемкая операция для больших таблиц
5. CROSS JOIN
SELECT a.*, b.*
FROM TableA a
CROSS JOIN TableB b;
- Возвращает все возможные комбинации строк
- Количество строк = M × N (где M и N - строки в таблицах)
- Опасен для больших таблиц (может создать огромный результат)
Специальные типы соединений в SQL Server
1. CROSS APPLY
SELECT d.DepartmentName, e.EmployeeName
FROM Departments d
CROSS APPLY dbo.GetDepartmentEmployees(d.DepartmentID) e;
- Выполняет функцию для каждой строки основной таблицы
- Возвращает только совпадающие результаты
2. OUTER APPLY
SELECT d.DepartmentName, e.EmployeeName
FROM Departments d
OUTER APPLY dbo.GetDepartmentEmployees(d.DepartmentID) e;
- Выполняет функцию для каждой строки
- Возвращает все строки основной таблицы, даже если функция не вернула результатов
3. SELF JOIN
SELECT e1.Name AS Employee, e2.Name AS Manager
FROM Employees e1
LEFT JOIN Employees e2 ON e1.ManagerID = e2.EmployeeID;
- Полезен для иерархических данных
- Требует разных псевдонимов для одной таблицы
Редко используемые соединения
1. NATURAL JOIN
- Соединяет таблицы по столбцам с одинаковыми именами
- Не рекомендуется (плохая читаемость, опасность ошибок)
2. EQUI JOIN vs NON-EQUI JOIN
-- EQUI JOIN (по равенству)
SELECT * FROM A JOIN B ON A.id = B.id;
-- NON-EQUI JOIN (по другим условиям)
SELECT * FROM A JOIN B ON A.value BETWEEN B.min AND B.max;
Оптимизация соединений
- Всегда используйте условия соединения (ON)
- Индексируйте столбцы, участвующие в соединениях
- Выбирайте правильный тип соединения под задачу
- Избегайте сложных выражений в условиях JOIN
- Анализируйте план выполнения для сложных запросов
Пример сравнения производительности
| Тип JOIN | Время выполнения (10K строк) | Память |
| INNER JOIN | 50ms | 10MB |
| LEFT JOIN | 80ms | 15MB |
| FULL JOIN | 200ms | 30MB |
| CROSS JOIN | 5000ms (5 сек) | 500MB |
Резюмируем
SQL Server поддерживает:
- Базовые соединения: INNER, LEFT, RIGHT, FULL, CROSS
- Специальные соединения: APPLY, SELF JOIN
- Разные алгоритмы: HASH JOIN, MERGE JOIN, LOOP JOIN
Ключевые принципы работы с JOIN:
- Выбирайте минимально необходимый тип соединения
- Всегда проверяйте условие соединения
- Индексируйте соединяемые столбцы
- Анализируйте план выполнения для сложных запросов