Функции MIN() и MAX() в SQL: минимальное и максимальное значение в группе и в окне

MIN() и MAX() возвращают наименьшее и наибольшее значение. Они работают не только с числами, но и с датами (самая ранняя/поздняя) и строками (по алфавиту). Как агрегаты они сворачивают группу, а с OVER работают как оконные функции — например, «максимум на текущий момент». Оба игнорируют NULL и возвращают NULL только для полностью пустого набора.

Синтаксис

MIN(выражение) / MAX(выражение) [OVER (PARTITION BY ... ORDER BY ...)]

Примеры использования

Пример 1: Минимум и максимум чека

SELECT
  MIN(amount) AS min_check,
  MAX(amount) AS max_check
FROM orders;

Результат:

min_check | max_check
----------+----------
150.00    | 9800.00

Пример 2: Первый и последний заказ пользователя

SELECT
  user_id,
  MIN(order_date) AS first_order,
  MAX(order_date) AS last_order
FROM orders
GROUP BY user_id;

Результат:

user_id | first_order | last_order
--------+-------------+------------
8       | 2026-01-12  | 2026-05-30
42      | 2026-02-03  | 2026-06-28

Пример 3: Максимум на текущий момент (оконная)

SELECT
  order_date,
  amount,
  MAX(amount) OVER (ORDER BY order_date) AS max_so_far
FROM orders;

Результат:

order_date | amount  | max_so_far
-----------+---------+-----------
2026-05-01 | 1200.00 | 1200.00
2026-05-02 | 1600.00 | 1600.00
2026-05-03 |  900.00 | 1600.00
Порешать SQL-задачи в тренажёре →

Типичная ошибка

На строках MIN/MAX сравнивают лексикографически (по алфавиту и collation), а не по длине, что легко перепутать. Чтобы получить не само минимальное значение, а строку целиком, где оно достигается (argmin), одной MIN() недостаточно — нужен оконный ROW_NUMBER() или подзапрос. NULL игнорируются, а пустой набор даёт NULL.

Где спрашивают на собеседовании

Классика — найти дату первого и последнего заказа пользователя через MIN(order_date)/MAX(order_date) с GROUP BY. На собесе просят достать строку с максимумом (argmax) — там уже нужен ROW_NUMBER().

FAQ: частые вопросы про MIN / MAX

Работают ли MIN() и MAX() с датами и текстом?

Да. Для дат вернут самую раннюю и самую позднюю, для строк — минимальную и максимальную по алфавиту (с учётом кодировки/collation). Тип результата совпадает с типом столбца.

Чем MIN() отличается от FIRST_VALUE()?

MIN() возвращает наименьшее значение независимо от порядка строк, а FIRST_VALUE() — значение первой строки в заданной сортировке окна. Если отсортировать окно по возрастанию того же столбца, они совпадут, но в общем случае это разные вещи.

Как получить всю строку, где достигается максимум?

Одной MAX() мало — она вернёт только значение. Используйте оконную ROW_NUMBER() OVER (ORDER BY x DESC) и отберите строку с номером 1, либо подзапрос с фильтром по MAX(x). Это классический вопрос про argmax на собесе.

Задачи в тренажёре по теме

Вопросы с собеседований по теме

Смежные темы SQL

Агрегации · Оконные функции

Другие функции SQL

ROW_NUMBER · RANK · DENSE_RANK · LAG · LEAD · NTILE

Открыть SQL-тренажёр (565 задач) →