SQL: выбор уникальных строк с минимальным значением

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

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

Если вам требуется быстрый результат, используйте функцию MIN() в сочетании с GROUP BY и выполните соединение с исходной таблицей. Допустим, у нас есть таблица orders, в которой необходимо отобразить заказ с самой низкой стоимостью для каждого изделия:

SQL
Скопировать код
SELECT o1.product_id, o1.price
FROM orders o1
JOIN (
    SELECT product_id, MIN(price) AS min_price
    FROM orders
    GROUP BY product_id
) o2 ON o1.product_id = o2.product_id AND o1.price = o2.min_price;

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

Подробнее о оконных функциях

Применение функции ROW_NUMBER()

Функция ROW_NUMBER() в SQL действует как волшебная палочка. Она способна выполнять чудеса, когда используется вместе с OVER и PARTITION BY:

SQL
Скопировать код
SELECT product_id, price
FROM (
  SELECT product_id,
         price,
         ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY price ASC) AS rn
  FROM orders
) ranked
WHERE rn = 1;

DISTINCT ON – ваш выбор в PostgreSQL

Если вы используете PostgreSQL и цените ясность и краткость, DISTINCT ON станет для вас надёжным помощником:

SQL
Скопировать код
SELECT DISTINCT ON (product_id) product_id, price
FROM orders
ORDER BY product_id, price ASC;

Проверенное временем применение подзапросов

Когда возникают сомнения, вы можете прибегнуть к подзапросам. Этот метод надёжен и проверен временем, подобно старому доброму гномику садовому:

SQL
Скопировать код
SELECT *
FROM orders o1
WHERE price = (
  SELECT MIN(price)
  FROM orders o2
  WHERE o1.product_id = o2.product_id
);

Управление несколькими группировками как профессионал

Группировка по нескольким критериям

Когда приходится группировать по нескольким столбцам, например, id и game, важно выбрать правильную стратегию использования GROUP BY:

SQL
Скопировать код
SELECT o1.id, o1.game, o1.point
FROM scores o1
JOIN (
    SELECT id, game, MIN(point) AS min_point
    FROM scores
    GROUP BY id, game
) o2 ON o1.id = o2.id AND o1.game = o2.game AND o1.point = o2.min_point;

FIRST_VALUE для выбора первых значений

Время от времени требуется извлечь первое значение из группы. SQL предоставляет такую возможность с помощью FIRST_VALUE:

SQL
Скопировать код
SELECT DISTINCT id, game,
       FIRST_VALUE(point) OVER (PARTITION BY id, game ORDER BY point ASC) AS min_point
FROM scores;

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

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

Markdown
Скопировать код
| Фотограф   | Заявка # | Баллы    |
| ---------- | -------- | -------- |
| Алиса      | 1        | 37       |
| Боб        | 2        | 29       |
| Чарли      | 3        | 22       |
| Алиса      | 4        | **14**   |
| Боб        | 5        | **15**   |
| Чарли      | 6        | **20**   |

Применив запрос:

SQL
Скопировать код
SELECT DISTINCT ON (photographer) *
FROM entries
ORDER BY photographer, score ASC;

Мы получим итоги:

Markdown
Скопировать код
| Фотограф (📷) | Лучший снимок (🏆) |
| ------------- | ------------------ |
| Алиса         | 14                 |
| Боб           | 15                 |
| Чарли         | 20                 |

Таким образом, мы увидим только лучшие работы 🥇 от каждого участника.

Устранение распространённых проблем

Значимость времени выполнения

Никогда не забывайте о времени выполнения запроса ⏰, особенно при работе с большими объемами данных. В таких случаях JOIN и подзапросы могут занять значительное время.

Особенности диалектов SQL

Всегда проверяйте совместимость 😎 ваших запросов, так как разные диалекты SQL имеют свои особенности.

Обработка ситуаций с одинаковыми значениями

Когда в данных возникает ситуация ничьей 🤼, добавьте в ORDER BY дополнительные столбцы для однозначной сортировки.

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

Для улучшения ваших навыков работы с SQL рекомендуем ознакомиться со следующими материалами 📚:

  1. Stack Overflow – SQL SELECT with DISTINCT on multiple columns
  2. Документация по SQL Server – Примеры SELECT (Transact-SQL)
  3. Документация по PostgreSQL – DISTINCT Clause
  4. TechOnTheNet – SQL: GROUP BY Clause