Выборка первых записей по уникальным значениям в MySQL

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Выбор строк с первым появлением каждого уникального значения можно реализовать путём использования самосоединения с фильтрацией по минимальному id:

SQL
Скопировать код
SELECT t1.*
FROM your_table AS t1
JOIN (
  SELECT MIN(id) AS MinId
  FROM your_table
  GROUP BY unique_column
) AS t2 ON t1.id = t2.MinId;

Здесь минимальное значение id обеспечивает выбор первого встречающегося элемента, а GROUP BY unique_column гарантирует уникальность значений. Этот подход простой и эффективный для быстрой реализации такой задачи.

Кинга Идем в IT: пошаговый план для смены профессии

Магия оконных функций: Продвинутый подход

Начиная с MySQL 8, оконные функции стали ещё одним способом упростить наши запросы и сделать их более эффективными:

SQL
Скопировать код
SELECT *
FROM (
  SELECT *, ROW_NUMBER() OVER (PARTITION BY unique_column ORDER BY sorting_column) AS rn
  FROM your_table
) AS sub
WHERE sub.rn = 1;

Функция ROW_NUMBER() пронумеровывает строки внутри группы, определённой unique_column, и выбирает первую строку каждой группы.

Существующие ограничения MySQL: Реальность

При работе с негруппированными колонками следует помнить об агрегатных функциях и включении полей в GROUP BY. В противном случае MySQL может пренебречь нарушением стандартов SQL, возвращая непредсказуемые результаты.

Распространенные ошибки и как их избежать: Чего не стоит делать

Использование MAX() в целях поиска первых уникальных значений является нелогичным, поскольку данная функция возвращает последний элемент. В таком случае лучше использовать MIN().

Визуализация

Давайте визуализируем это. Представим таблицу базы данных в виде участников гонки, где у каждого уникального значения есть своя эстафетная палочка 👟:

Markdown
Скопировать код
🏁: [🏃‍♂️7️⃣, 🏃‍♂️5️⃣, 🏃‍♂️3️⃣, 🏃‍♂️7️⃣, 🏃‍♂️5️⃣, 🏃‍♀️2️⃣]

Задача MySQL – выбрать первого бегуна для каждой палочки:

SQL
Скопировать код
SELECT * FROM runners WHERE baton = FIRST_OCCURRENCE;

И вот наши призёры:

Markdown
Скопировать код
🥇: [🏃‍♂️7️⃣, 🏃‍♂️5️⃣, 🏃‍♂️3️⃣, 🏃‍♀️2️⃣]

Среди призёров нет повторов – по одной строке для каждой уникальной записи!

Продвинутые запросы для умных решений

Если требуется всё содержимое строки, а не просто id, то следует использовать соединение с подзапросом:

SQL
Скопировать код
SELECT t1.*
FROM your_table AS t1
INNER JOIN (
  SELECT unique_column, MIN(time) AS MinTime
  FROM your_table
  GROUP BY unique_column
) AS t2 ON t1.unique_column = t2.unique_column AND t1.time = t2.MinTime;

Сценарии применения в реальной жизни

Этот метод подойдёт для различных целей:

  • Поиск первой покупки каждого клиента.
  • Определение времени первого входа в систему пользователем.
  • Получение первых данных от датчиков каждого устройства.

Важность производительности: Оптимизация ваших запросов

Чтобы увеличить скорость и эффективность ваших запросов, особенно при работе с большими объёмами данных, убедитесь, что все колонки в JOIN, WHERE и ORDER BY проиндексированы. Правильная индексация делает запросы быстрыми и эффективными.

Полезные материалы

  1. MySQL :: Руководство по MySQL 8.0 :: 14.19.3 Обработка GROUP BY в MySQL — Подробный разбор работы с GROUP BY.
  2. PostgreSQL DISTINCT ON with different ORDER BY – Stack Overflow — Обсуждение подхода к выборке уникальных строк в PostgreSQL.
  3. MySQL :: Руководство по MySQL 8.0 :: 14.20 Оконные функции — Детальное описание синтаксиса и использования оконных функций.
  4. Fetch the rows which have the Max value for a column for each distinct value of another column – Stack Overflow — Обсуждение использования соединений для отбора уникальных значений.
  5. SQL Indexing and Tuning e-Book for developers: Use The Index, Luke — Рекомендации по оптимизации SQL запросов через индексирование.
  6. SQL GROUP BY | Intermediate SQL – Mode — Глубокий дайв в GROUP BY в SQL.