JavaRush /Курсы /SQL SELF /Функции GREATEST() и LEAST() и NULL

Функции GREATEST() и LEAST() и NULL

SQL SELF
10 уровень , 2 лекция
Открыта

Сегодня мы погружаемся в еще более специфическую, но важную тему: функции GREATEST() и LEAST(). Вы узнаете, как находить максимальные и минимальные значения из нескольких столбцов, и, самое главное, как NULL влияет на их работу.

Если вы когда-то искали самое главное в своей жизни (любовь, работу мечты или лучший рецепт пиццы), то вы сразу поймёте, для чего нужны функции GREATEST() и LEAST(). Эти функции помогают найти самое большое или самое маленькое значение в списке вещей. Только вместо пиццы вы работаете с числами, датами, строками и другими данными в PostgreSQL.

GREATEST()

GREATEST() возвращает самое большое значение из переданного набора.

Синтаксис:

GREATEST(value1, value2, ..., valueN)

LEAST()

LEAST() делает обратное: она ищет самое маленькое значение.

Синтаксис:

LEAST(value1, value2, ..., valueN)

Пример:

Предположим, у нас есть таблица students_scores, где хранятся оценки студентов за три экзамена:

student_id exam_1 exam_2 exam_3
1 85 90 82
2 NULL 76 89
3 94 NULL 88

Применение GREATEST() и LEAST():

SELECT
    student_id,
    GREATEST(exam_1, exam_2, exam_3) AS highest_score,
    LEAST(exam_1, exam_2, exam_3) AS lowest_score
FROM students_scores;

Результат:

student_id highest_score lowest_score
1 90 82
2 89 NULL
3 94 NULL

Как NULL влияет на GREATEST() и LEAST()

Теперь мы подходим к самому интересному. Вместе со значениями в таблице могут быть и NULL. А как мы уже знаем, NULL — это загадочная сущность, которая обозначает отсутствие данных или неизвестное значение. Давайте разберёмся, что происходит, если NULL попадает в функции GREATEST() и LEAST() в PostgreSQL.

Поведение NULL:

В PostgreSQL функции GREATEST() и LEAST() имеют особенное поведение: они игнорируют значения NULL при поиске наибольшего или наименьшего значения среди своих аргументов. Важно: Единственный случай, когда эти функции вернут NULL, это если все их аргументы являются NULL.

Пример:

SELECT
    GREATEST(10, 20, NULL, 5) AS greatest_value,
    LEAST(10, 20, NULL, 5) AS least_value;

Результат:

greatest_value least_value
20 5

Как видите, NULL был проигнорирован, и функции вернули наибольшее и наименьшее значения из присутствующих (10, 20, 5).

А вот пример, когда все аргументы NULL:

Пример:

SELECT
    GREATEST(NULL, NULL) AS greatest_nulls,
    LEAST(NULL, NULL) AS least_nulls;

Результат:

greatest_nulls least_nulls
NULL NULL

Как избежать проблем с NULL?

Хотя PostgreSQL по умолчанию игнорирует NULL, иногда вам может потребоваться иное поведение. Например, если вы хотите, чтобы NULL рассматривался как конкретное значение (например, 0 или другое значение по умолчанию) при определении наибольшего/наименьшего. В таких случаях можно использовать функцию COALESCE().

Функция COALESCE(arg1, arg2, ...) возвращает первый не-NULL аргумент из своего списка. Это позволяет предварительно заменить NULL на осмысленное значение перед передачей в GREATEST() или LEAST().

Пример 1: Замена NULL на 0

Допустим, мы хотим считать, что отсутствие оценки NULL эквивалентно 0. Мы можем использовать COALESCE() для подстановки значения по умолчанию.

Вот наша исходная таблица:

student_id exam_1 exam_2 exam_3
1 90 85 82
2 NULL 89 NULL
3 NULL NULL 94

Запрос:

SELECT
    student_id,
    GREATEST(
        COALESCE(exam_1, 0), 
        COALESCE(exam_2, 0), 
        COALESCE(exam_3, 0)
    ) AS highest_score,
    LEAST(
        COALESCE(exam_1, 0), 
        COALESCE(exam_2, 0), 
        COALESCE(exam_3, 0)
    ) AS lowest_score
FROM students_scores;

Результат:

student_id highest_score lowest_score
1 90 82
2 89 0
3 94 0

Пример 2: Замена NULL на значение из другого столбца

Иногда вместо фиксированного значения (например, 0) нам нужно подставить значение из другого столбца. Например, если exam_3 отсутствует, мы хотим использовать значение из exam_1.

SELECT
    student_id,
    GREATEST(
        exam_1, 
        exam_2, 
        COALESCE(exam_3, exam_1)
    ) AS highest_score
FROM students_scores;

Допустим, у нас есть такая таблица:

student_id exam_1 exam_2 exam_3
1 90 85 82
2 NULL 89 NULL
3 70 NULL NULL

Результат работы запроса:

student_id highest_score
1 90
2 89
3 70

Практические кейсы

Кейc 1: Поиск максимальной скидки

order_id discount_1 discount_2 discount_3
101 5 10 7
102 NULL 3 8
103 15 NULL NULL
104 NULL NULL NULL

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

SELECT
    order_id,
    GREATEST(discount_1, discount_2, discount_3) AS max_discount
FROM orders;

Результат:

order_id max_discount
101 10
102 8
103 15
104 NULL

Кейc 2: Поиск минимальной цены товара

В таблице products хранятся цены товаров в трёх валютах (USD, EUR, GBP). Ваша задача — найти минимальную цену для каждого товара.

product_id price_usd price_eur price_gbp
1 100 95 80
2 NULL 150 140
3 200 NULL NULL
4 NULL NULL NULL
SELECT
    product_id,
    LEAST(price_usd, price_eur, price_gbp) AS lowest_price
FROM products;
product_id lowest_price
1 80
2 140
3 200
4 NULL

Если все цены NULL, результат тоже NULL

Типичные ошибки при использовании GREATEST() и LEAST()

Ошибка 1: Непредвиденный результат из-за NULL.

Ранее в лекции мы подробно разобрали, как NULL влияет на GREATEST() и LEAST() в PostgreSQL. Основная ошибка заключается в том, что пользователи, привыкшие к поведению NULL в других СУБД (где один NULL "отравляет" весь результат), ожидают такого же поведения и от PostgreSQL.

Как проявляется ошибка: Вы можете ошибочно полагать, что если в списке аргументов есть NULL, функция всегда вернёт NULL. В результате, вы можете без необходимости применять COALESCE() ко всем аргументам, что может усложнить запрос и замедлить его выполнение, если в вашем сценарии NULL должен быть просто проигнорирован.

Ошибка 2: Использование GREATEST() и LEAST() с несовместимыми типами.

Функции GREATEST() и LEAST() предназначены для сравнения значений одного и того же типа данных или типов, которые могут быть неявно приведены друг к другу. Попытка сравнить значения совершенно разных, несовместимых типов, приведет к ошибке.

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

2
Задача
SQL SELF, 10 уровень, 2 лекция
Недоступна
Использование `GREATEST()` и `LEAST()`
Использование `GREATEST()` и `LEAST()`
2
Задача
SQL SELF, 10 уровень, 2 лекция
Недоступна
Использование `COALESCE()` с `GREATEST()` и `LEAST()`
Использование `COALESCE()` с `GREATEST()` и `LEAST()`
Комментарии (5)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Артем Уровень 11
5 января 2026
10 октября 2025
И не MySQL и не PostgreSQL
Anton Zhukov Уровень 12
25 июня 2025
Используйте функции `GREATEST()` и `LEAST()` без использования `COALESCE` для корректного учета `NULL` значений. :D
24 июня 2025
Функции GREATEST() и LEAST() в разных СУБД работают по разному: * MySQL - Если какой-либо аргумент NULL, результат является NULL. Никаких сравнений не требуется. * PostgreSQL - Значения NULL в этом списке игнорируются, так что результат выражения будет равен NULL, только если все его аргументы равны NULL. GREATEST и LEAST Получается что описание функций дано для иных СУБД.
Серега Батенин Уровень 12
24 июня 2025
Дибилизм. В первой задаче валидатор говорит используйте coalesce, идешь смотришь "правильное" решение, оно один в один как у тебя, но твое не засчитывают, а их проходит без всяких coalesce