Какая функция в SQL возвращает максимальное значение
Что проверяют
Ответ MAX() знают все, поэтому интервьюер копает глубже: как функция обходится с NULL, как достать всю строку с максимумом и как прочитать результат из Java. Типичный следующий вопрос: «Найдите вторую по величине зарплату».
Как отвечать
MAX(column) это агрегатная функция, она возвращает наибольшее значение в группе. Детали, которые стоит назвать сразу:
- NULL: пропускается. На пустом наборе без
GROUP BYзапрос вернёт одну строку со значениемNULL, а не ноль строк; - типы: числа, даты и строки. Строки сравниваются по правилам сортировки, поэтому
'9' > '10'; - группы: с
GROUP BYмаксимум считается по каждой группе, а условие на агрегат пишется вHAVING; - строка с максимумом:
MAXотдаёт значение, а не запись. Всю запись берут черезORDER BY salary DESCсLIMIT 1илиFETCH FIRST 1 ROWS ONLY, а максимум в каждой группе черезRANK() OVER (PARTITION BY ...), который сохранит ничьи; - максимум по строке: из нескольких колонок одной строки берут
GREATEST(a, b), это не агрегат; - производительность: с B-tree индексом по колонке PostgreSQL и MySQL берут максимум с края индекса, без полного сканирования.
Из Java: в JPQL select max(e.salary) from Employee e, в Spring Data метод findTopByOrderBySalaryDesc(). На пустой таблице getSingleResult() вернёт null, а в JDBC getLong() превратит NULL в 0, поэтому проверяйте wasNull() или читайте через getObject(1, Long.class).
Где спотыкаются
Пишут SELECT name, MAX(salary) FROM employees без группировки и ждут имя самого высокооплачиваемого. PostgreSQL выдаст ошибку, а MySQL без режима ONLY_FULL_GROUP_BY вернёт имя из произвольной строки.
Пишут WHERE salary = MAX(salary). Агрегат в WHERE недопустим, нужен подзапрос или оконная функция.
Для второй зарплаты делают LIMIT 1 OFFSET 1 и ошибаются на дублях. Надёжнее DENSE_RANK() или максимум среди значений меньше общего максимума.