0Pricing
SQL Academy · Урок

Сравнение строк в одной таблице

Находите пары и взаимосвязи

«Сравнение строк в одной таблице» — бесплатный урок 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 — локальная установка не требуется.

Все уроки этого курса

  1. Что такое самосоединение
  2. Сотрудники и руководители
  3. Сравнение строк в одной таблице
  4. Ограничения самосоединений
← Назад к SQL Academy