datarekha
SQL Easy Asked at GoogleAsked at Amazon

What aggregate functions does SQL provide, and what are the subtle behaviours of MIN/MAX on non-numeric types?

The short answer

SQL's standard aggregate functions are COUNT, SUM, AVG, MIN, and MAX. MIN and MAX work on any orderable type including strings and dates, using the type's collation or sort order, which surprises analysts who expect numeric-only semantics.

How to think about it

The interviewer is probing the edges, not the definitions — specifically how NULLs flow through aggregates and what MIN/MAX really do on dates and strings. Anyone can recite the five functions; the ones who stand out reason through a tricky NULL case on the spot.

FunctionInputNULLsNotes
COUNT(*)anycountedcounts rows
COUNT(col)anyskippedcounts non-NULL values
SUM(col)numericskippedNULL if every input is NULL
AVG(col)numericskippeddenominator = non-NULL count
MIN(col)any orderableskippedworks on strings, dates
MAX(col)any orderableskippedworks on strings, dates

A worked example

One query exercises every edge at once — note that Eggplant has a NULL price:

-- products(name, category, price, launched_on)
-- 'Eggplant' has a NULL price; names mix upper- and lower-case

SELECT COUNT(*)                AS total_rows,       -- all 5 rows
       COUNT(price)            AS rows_with_price,  -- skips the NULL
       ROUND(AVG(price), 2)    AS avg_price,        -- divides by 4, not 5
       MIN(name)               AS first_alpha,
       MAX(name)               AS last_alpha,
       MIN(launched_on)        AS earliest_launch,  -- string dates sort correctly
       COALESCE(SUM(price), 0) AS total_price_safe
FROM products;
total_rowsrows_with_priceavg_pricefirst_alphalast_alphaearliest_launchtotal_price_safe
541.63Applecherry2022-11-106.5

Three things to read off it. COUNT(*) is 5 but COUNT(price) is 4 — the NULL price is skipped, and AVG divides by that same 4, not by 5 (a classic source of “why is my average too high?”). MIN(name) is Apple and MAX(name) is cherry — a string comparison, and because uppercase sorts before lowercase in this collation, lowercase cherry lands last. And MIN(launched_on) works straight off the ISO date strings, since '2022-...' sorts before '2023-...' lexicographically.

MIN/MAX on non-numerics

That last point is the one that surprises people: MIN/MAX work on any type with a defined sort order — dates, timestamps, strings. For strings the comparison is lexicographic, following the column’s collation, so whether 'Apple' < 'banana' holds depends on whether that collation is case-sensitive.

The integer-division gotcha

On some engines (older PostgreSQL with an integer column), AVG over integers does integer division and truncates the decimal. Cast to be safe:

SELECT AVG(CAST(price AS NUMERIC)) FROM products;   -- safe across engines
Learn it properly Aggregates & GROUP BY

Keep practising

All SQL questions

Explore further

Skip to content