Сравнение строк в одной таблице
Находите пары и взаимосвязи
«Сравнение строк в одной таблице» — бесплатный урок SQL Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения SQL Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс SQL Academy содержит 4 уроков всего.
Что такое самосоединение
Самосоединение — это соединение таблицы с самой собой. Сначала это может показаться необычным, но это мощный приём для сравнения строк внутри одной таблицы.
Представьте таблицу employees, где у каждого сотрудника есть manager_id, указывающий на другую строку в той же таблице. Самосоединение позволяет сопоставить каждого сотрудника с его руководителем в одном запросе.
Настройка таблицы для примера
Создадим простую таблицу employees, которую будем использовать на протяжении всего урока. В каждой строке есть id, name, salary и manager_id, ссылающийся на другого сотрудника в той же таблице.
CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(50),
salary INT,
manager_id INT
);
INSERT INTO employees VALUES
(1, 'Alice', 90000, NULL),
(2, 'Bob', 70000, 1),
(3, 'Carol', 65000, 1),
(4, 'Dave', 55000, 2),
(5, 'Eve', 60000, 2),
(6, 'Frank', 48000, 3);Базовый синтаксис самосоединения
Чтобы выполнить самосоединение, укажите одну и ту же таблицу дважды, используя два разных псевдонима. Псевдонимы работают так, словно у Вас есть две отдельные копии таблицы. Затем укажите условие соединения, связывающее эти две копии.
Здесь мы задаём для employees псевдоним e (сотрудник), а для руководителя — m, после чего сопоставляем строки по условию e.manager_id = m.id.
SELECT
e.name AS employee,
m.name AS manager
FROM employees e
JOIN employees m ON e.manager_id = m.id;Включение строк верхнего уровня с помощью LEFT JOIN
Обычный INNER JOIN удаляет строки, в которых manager_id равен NULL, а значит, сотрудник верхнего уровня (Алиса, CEO) не попадёт в результаты.
Используйте LEFT JOIN, чтобы появился каждый сотрудник, в том числе сотрудник без руководителя. Для таких сотрудников в столбце руководителя будет просто указано NULL.
SELECT
e.name AS employee,
m.name AS manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id
ORDER BY m.name NULLS LAST, e.name;Поиск пар с общим свойством
Самосоединения также полезны для поиска пар строк с одинаковым значением. Например, можно найти все пары сотрудников, которые подчиняются одному и тому же руководителю.
Условие a.id < b.id не позволяет дублировать пары: например, пары (Боб, Кэрол) и (Кэрол, Боб) не появятся в результатах одновременно.
SELECT
a.name AS employee_1,
b.name AS employee_2,
a.manager_id AS shared_manager
FROM employees a
JOIN employees b
ON a.manager_id = b.manager_id
AND a.id < b.id;Сравнение зарплат в разных строках
С помощью самосоединения можно сравнивать числовые значения в разных строках. Приведённый ниже запрос находит каждого сотрудника, чья зарплата выше зарплаты его собственного руководителя, — это классическая аналитическая проверка.
SELECT
e.name AS employee,
e.salary AS emp_salary,
m.name AS manager,
m.salary AS mgr_salary
FROM employees e
JOIN employees m ON e.manager_id = m.id
WHERE e.salary > m.salary;Поиск строк без совпадения
Самосоединение с LEFT JOIN и проверкой WHERE ... IS NULL позволяет найти строки, у которых нет соответствующей пары. Здесь мы находим сотрудников, у которых нет подчинённых, — конечные узлы иерархии.
SELECT e.name AS employee
FROM employees e
LEFT JOIN employees sub ON sub.manager_id = e.id
WHERE sub.id IS NULL
ORDER BY e.name;Подсчёт непосредственных подчинённых
Соединив таблицу с самой собой и сгруппировав строки по стороне руководителя, можно подсчитать количество непосредственных подчинённых у каждого руководителя. Сотрудники без подчинённых включаются благодаря LEFT JOIN.
SELECT
m.name AS manager,
COUNT(e.id) AS direct_reports
FROM employees m
LEFT JOIN employees e ON e.manager_id = m.id
GROUP BY m.id, m.name
ORDER BY direct_reports DESC;Использование CTE для упрощения самосоединений
Когда запрос с самосоединением становится сложным, его заключение в общее табличное выражение (CTE) упрощает чтение логики. Определите одно CTE для иерархии, а затем выполняйте понятный запрос к нему.
WITH hierarchy AS (
SELECT
e.id AS emp_id,
e.name AS employee,
e.salary AS emp_salary,
m.name AS manager,
m.salary AS mgr_salary
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id
)
SELECT *
FROM hierarchy
WHERE mgr_salary IS NOT NULL
AND emp_salary > mgr_salary;Самосоединение неиерархической таблицы
Самосоединения применяются не только к иерархиям руководителей и сотрудников. В приведённом ниже примере таблица products используется для поиска всех пар товаров, относящихся к одной и той же категории, что полезно для рекомендательных систем или проверки сходства.
CREATE TABLE products (
id INT PRIMARY KEY,
name VARCHAR(50),
category VARCHAR(30)
);
INSERT INTO products VALUES
(1, 'Laptop', 'Electronics'),
(2, 'Phone', 'Electronics'),
(3, 'Tablet', 'Electronics'),
(4, 'Shirt', 'Clothing'),
(5, 'Jeans', 'Clothing');
SELECT
a.name AS product_1,
b.name AS product_2,
a.category
FROM products a
JOIN products b
ON a.category = b.category
AND a.id < b.id;Типичные ошибки: декартовы произведения и дубликаты
Две распространённые ошибки при использовании самосоединений — это декартовы произведения (полное отсутствие условия соединения) и повторяющиеся пары (использование a.id <> b.id вместо a.id < b.id).
Всегда проверяйте правильность условия соединения и используйте < вместо <>, когда нужны только неупорядоченные пары, а не упорядоченные.
-- Wrong: returns every ordered pair (A,B) AND (B,A)
SELECT a.name, b.name
FROM employees a
JOIN employees b ON a.manager_id = b.manager_id
AND a.id <> b.id;
-- Correct: returns each unordered pair once
SELECT a.name, b.name
FROM employees a
JOIN employees b ON a.manager_id = b.manager_id
AND a.id < b.id;Быстрая проверка
Проверьте, насколько хорошо Вы поняли самосоединения и сравнение строк в одной таблице.
Итоги урока
В этом уроке Вы узнали, как использовать самосоединения для сравнения строк в одной таблице.
Основные выводы:
- Задавайте таблице два псевдонима (например,
eиm), чтобы база данных воспринимала их как отдельные источники. - Используйте
INNER JOIN, когда нужны только строки, для которых найдено соответствие, иLEFT JOIN, когда нужно включить также строки без соответствий. - Используйте
a.id < b.id, чтобы избежать дублирования неупорядоченных пар. - Самосоединения подходят для иерархий (руководитель/сотрудник), поиска похожих объектов (одинаковая категория) и любых сравнений, в которых нужно связать две строки одной таблицы.
- CTE могут значительно упростить чтение и сопровождение сложных запросов с самосоединениями.
Часто задаваемые вопросы
Урок «Сравнение строк в одной таблице» бесплатный?
Да — полный текст урока «Сравнение строк в одной таблице» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс SQL Academy, подпишись на CoddyKit PRO. Курс SQL Academy содержит 4 уроков всего.
Чему я научусь в уроке «Сравнение строк в одной таблице»?
Находите пары и взаимосвязи Ты практикуешь SQL Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать SQL Academy?
Предыдущий опыт не требуется. SQL Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Сравнение строк в одной таблице»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке SQL Academy?
Да. Каждый урок SQL Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Что такое самосоединение
- Сотрудники и руководители
- Сравнение строк в одной таблице
- Ограничения самосоединений