0Pricing
SQL Interview Prep · Урок

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

Шаблоны самообъединения для поиска пар, дубликатов и соседних записей.

«Сравнение строк внутри одной таблицы» — бесплатный урок SQL Interview Prep на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения SQL Interview Prep, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс SQL Interview Prep содержит 4 уроков всего.

Самосоединения для сравнения строк друг с другом

Помимо иерархий, другое важное применение самосоединения — сравнение строк одной таблицы между собой. Вместо связи «родитель — потомок» вы сопоставляете произвольные строки, чтобы найти дубликаты, почти совпадающие или соседние записи.

Шаблон тот же: назначьте таблице два псевдонима и запишите условие ON, выражающее связь между двумя строками, которые нужно сопоставить.

Поиск пар в одной группе

Классический вопрос: найти все пары сотрудников, работающих в одном отделе. Соедините таблицу с самой собой по совпадающему отделу, но оставьте две строки различными.

Наивное соединение также сопоставит каждого сотрудника с самим собой и создаст каждую пару дважды. Далее мы это исправим.

SELECT a.name, b.name, a.department
FROM employees a
JOIN employees b ON a.department = b.department;

Устранение пар строки с самой собой и зеркальных дубликатов

При поиске пар в одной группе возникают две проблемы: строка сопоставляется сама с собой (Алиса с Алисой), а каждая пара появляется дважды (Алиса—Боб и Боб—Алиса).

Исправьте обе проблемы одним неравенством: a.id < b.id. Это гарантирует, что две строки различны, и оставляет только один порядок каждой пары.

SELECT a.name, b.name, a.department
FROM employees a
JOIN employees b
  ON a.department = b.department
 AND a.id < b.id;

Почему a.id < b.id, а не a.id <> b.id

Использование a.id <> b.id устраняет пары строки с самой собой, но по-прежнему возвращает оба порядка, удваивая результат. Использование a.id < b.id одновременно устраняет пары строки с самой собой и удаляет зеркальный дубликат.

Интервьюеры специально обращают внимание на выбор между < и <>: это показывает, что вы понимаете комбинаторику самосоединений.

-- <>  keeps Alice-Bob AND Bob-Alice (duplicated)
-- <   keeps only Alice-Bob (correct unique pairs)

Поиск дублирующихся строк

Чтобы найти записи, дублирующие друг друга по ключевым столбцам, выполните самосоединение по этим столбцам и потребуйте разные первичные ключи.

Здесь мы выявляем клиентов с одинаковым адресом электронной почты. Условие a.id < b.id оставляет каждую пару дубликатов один раз. Часто конструкция GROUP BY ... HAVING COUNT(*) > 1 понятнее, но самосоединение показывает реальные проблемные пары рядом.

SELECT a.id, b.id, a.email
FROM customers a
JOIN customers b
  ON a.email = b.email
 AND a.id < b.id;

Сравнение соседних записей

Частая задача аналитика: сравнить каждую строку со следующей в последовательности, например продажи за каждый день с предыдущим днём. Самосоединение может сопоставить последовательные строки.

Здесь мы соединяем каждый день со строкой ровно на один день раньше, чтобы вычислить разницу. Это работает, если в последовательности нет пропусков.

SELECT t.day, t.amount,
       t.amount - y.amount AS change_vs_prev
FROM daily_sales t
JOIN daily_sales y
  ON y.day = t.day - INTERVAL '1 day';

Проблема пропусков при самосоединении соседних строк

Предыдущий запрос ломается, если какой-то день отсутствует: строки ровно за один день до него нет, поэтому эта строка выпадает (при внутреннем соединении), либо вам приходится обрабатывать NULL.

Поэтому на собеседованиях часто предлагают использовать оконные функции, например LAG, для задачи «сравнить с предыдущей строкой»: они используют порядковую позицию, а не сопоставление значений, и корректно работают с пропусками.

-- LAG handles gaps; the self join assumed contiguous days
SELECT day, amount,
       amount - LAG(amount) OVER (ORDER BY day) AS change_vs_prev
FROM daily_sales;

Самосоединение и оконная функция

Важно понимать компромисс:

  • самосоединение сопоставляет строки по связи значений (одинаковый отдел, более ранняя дата). Это гибкий подход, но он может размножать строки и некорректно обрабатывать пропуски.
  • оконная функция сопоставляет строки по порядковой позиции внутри упорядоченного раздела. Это более понятный способ реализовать логику предыдущей и следующей строки.

Для задачи «сравнить с соседней строкой» предпочитайте LAG/LEAD. Для задачи «найти все пары, соответствующие условию» естественным инструментом будет самосоединение.

Поиск строк, превосходящих своих коллег

Ещё один шаблон: найти сотрудников, которые зарабатывают больше хотя бы одного коллеги в своём отделе. Самосоединение выражает это условие напрямую.

Мы соединяем каждого сотрудника с другими сотрудниками того же отдела, которые зарабатывают меньше, а затем оставляем уникальных сотрудников, которые встретились в результате. Такой запрос почти дословно соответствует предложению на русском языке.

SELECT DISTINCT a.name, a.department, a.salary
FROM employees a
JOIN employees b
  ON a.department = b.department
 AND a.salary > b.salary;

Следите за размножением строк

Самосоединение по неуникальному столбцу размножает строки. Объединение внутри отдела из 100 человек создаёт примерно 100 x 100 возможных пар ещё до фильтрации.

Всегда добавляйте предикат устранения дубликатов (a.id < b.id) и используйте DISTINCT или группировку, если нужны только участвующие строки, а не каждая пара. На собеседованиях упоминайте, что учитываете такое размножение строк.

Выбор инструмента для сравнения

Как выбрать способ сравнения внутри таблицы:

  • Все совпадающие пары (дубликаты, комбинации внутри одной группы): самосоединение с a.id < b.id.
  • Предыдущая или следующая строка в определённом порядке: оконная функция (LAG/LEAD).
  • Сравнение каждой строки с агрегатом группы: коррелированный подзапрос или оконный агрегат.

Быстрая проверка

Вам нужны все уникальные пары товаров из одной категории, при этом товар не должен образовывать пару с самим собой, а порядок товаров в паре не должен создавать дубликаты.

Итоги: сравнение строк внутри одной таблицы

Главные выводы:

  • Соединяйте таблицу саму с собой, чтобы объединять её строки при поиске дубликатов и комбинаций внутри одной группы.
  • Используйте a.id < b.id, чтобы одним предикатом исключить пары строки с самой собой и зеркальные дубликаты.
  • Сравнение соседних строк с помощью самосоединения нарушается при наличии пропусков; для логики предыдущей и следующей строки предпочитайте LAG/LEAD.
  • При соединении по неуникальным столбцам всегда учитывайте размножение строк.

Часто задаваемые вопросы

Урок «Сравнение строк внутри одной таблицы» бесплатный?

Да — полный текст урока «Сравнение строк внутри одной таблицы» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс SQL Interview Prep, подпишись на CoddyKit PRO. Курс SQL Interview Prep содержит 4 уроков всего.

Чему я научусь в уроке «Сравнение строк внутри одной таблицы»?

Шаблоны самообъединения для поиска пар, дубликатов и соседних записей. Ты практикуешь SQL Interview Prep с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать SQL Interview Prep?

Предыдущий опыт не требуется. SQL Interview Prep на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Сравнение строк внутри одной таблицы»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке SQL Interview Prep?

Да. Каждый урок SQL Interview Prep включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

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

  1. CROSS JOIN и декартовы произведения
  2. SELF JOIN для иерархий
  3. Сравнение строк внутри одной таблицы
  4. Выбор правильного типа объединения
← Назад к SQL Interview Prep