SQL-Engineering-Handbook

MIN() and MAX()

Introduction

MIN() and MAX() find the smallest and largest values in a column. They look like the simplest aggregates in the module, but they’re the only two that work natively across numbers, dates, and text — which makes them more versatile, and more prone to surprising behavior on non-numeric columns, than SUM() or AVG().

Learning Objectives

Concept Overview

Function Returns
MIN(column) The smallest non-NULL value
MAX(column) The largest non-NULL value

MIN() and MAX() across numeric, date, and text columns

Business Context

“What was our highest sale of the month?” “Who’s been here the longest?” “What’s the earliest unfulfilled order?” — every one of these is a MIN()/MAX() query, and they’re often the first thing an executive asks after seeing a SUM() or AVG() figure.

Where Companies Use It

Syntax

SELECT MIN(column_name) FROM table_name;
SELECT MAX(column_name) FROM table_name;

Execution Flow

salary column: [50000, NULL, 62000, 40000]

MIN() -> 40000   (NULL ignored, smallest of the rest)
MAX() -> 62000   (NULL ignored, largest of the rest)

Engineering Notes

MySQL Notes

MySQL evaluates string MIN()/MAX() using the column’s collation (commonly case-insensitive by default, e.g. utf8mb4_general_ci).

PostgreSQL Notes

PostgreSQL string comparisons are case-sensitive by default ('Z' < 'a' in the default C-adjacent locale in many setups) — MIN()/MAX() on text can return different results than the “same” query in MySQL. Always verify collation when porting reports between the two.

Edge Cases

Common Mistakes

Wrong — trying to get the entire row containing the max salary using only MAX():

-- This does NOT return the employee with the highest salary —
-- it mixes an aggregate with a non-aggregated column with no
-- GROUP BY, which is invalid or misleading depending on the engine.
SELECT emp_name, MAX(salary) FROM employes;

Correct — use ORDER BY ... LIMIT (covered in Module 01) or a window function (Module 07) to retrieve the full row:

SELECT emp_name, salary
FROM employes
ORDER BY salary DESC
LIMIT 1;

Interview Questions

  1. Why can’t you reliably get “the employee with the highest salary” using MAX(salary) alone in a SELECT with other non-aggregated columns?
  2. What does MIN() return on an empty result set?
  3. Why might MAX(employee_name) return a different “largest” name in MySQL vs. PostgreSQL on the same data?

Summary

MIN()/MAX() find extremes across numeric, date, and text data, ignoring NULL. They cannot pull an entire related row on their own — for that, pair ORDER BY with LIMIT, or use a window function.

Practice Challenges

  1. Find the earliest and latest emp_id per department using GROUP BY.
  2. Find the highest-paid employee’s full row (name, department, salary) using ORDER BY ... LIMIT 1 instead of MAX().

Further Reading


Related Topics: COUNT() · GROUP BY · Window Functions (Module 07)


← Previous Lesson ↑ Module README Next Lesson →