MAX() returns the largest non-NULL value in a group, with NULL returned when the group contains no known candidate.
MAX is useful for the highest amount, newest recorded date or largest measured value. It summarises one expression. It does not automatically return other columns from the row where that maximum occurred.
This reference adds detail to the main course. You can read it independently: the small database below supplies every table and row used in the examples. Start with the question each query answers, then compare the returned values with the data rather than memorising a line of syntax.
Set up the practice database
Run this setup once in a new practice database, before the examples. It uses four customers and six sales. Ana has two sales, Ben has one, Cara has two, and Dev has none.
Sale 106 has no customer link; sale 104 has an unknown amount. These deliberate test cases expose missing information and unmatched relationships.
CREATE TABLE customers (
id INTEGER PRIMARY KEY,
name VARCHAR(40) NOT NULL,
city VARCHAR(40),
manager_id INTEGER
);
CREATE TABLE sales (
id INTEGER PRIMARY KEY,
customer_id INTEGER,
amount DECIMAL(10,2),
status VARCHAR(20) NOT NULL,
created_on DATE NOT NULL
);
INSERT INTO customers (id,name,city,manager_id) VALUES
(1,'Ana','Leeds',NULL),(2,'Ben','Leeds',1),
(3,'Cara','Porto',1),(4,'Dev',NULL,2);
INSERT INTO sales (id,customer_id,amount,status,created_on) VALUES
(101,1,10,'paid','2026-01-01'),
(102,1,30,'pending','2026-01-02'),
(103,2,20,'paid','2026-01-02'),
(104,3,NULL,'pending','2026-02-01'),
(105,3,20,'paid','2026-02-02'),
(106,NULL,5,'paid','2026-02-03');An amount of zero would be a known value. The NULL amount here means the value is unknown. A customer with no matching sale differs from a sale whose customer_id is NULL.
The primary keys identify individual records even when amounts or cities repeat. Dates use year-month-day format. The examples specify sorting whenever order matters; insertion order alone does not guarantee display order.
How MAX() works
MAX(amount) compares the known amounts and returns thirty in the supplied sales table. The missing amount in sale 104 does not compete. An unknown maximum is represented by NULL when no known value exists, including an aggregate over an empty filtered input. That distinction matters: zero can be a real maximum when all amounts are zero, while NULL means there was no known candidate.
GROUP BY changes the scope of the maximum. MAX(amount) over the whole table returns one value, while GROUP BY customer_id returns one maximum per customer link. A maximum is not a sum or a count: several smaller purchases never combine into a larger maximum. Customer 1’s ten and thirty produce thirty rather than forty. Use SUM for total purchasing value and keep the output alias clear enough that a reader can tell which measure is being reported.
The latest date with MAX()
MAX(created_on) returns the latest saved date in a comparable date column. It answers when the latest event was recorded, but not automatically which status or customer belonged to that event. If two sales share that date, both correspond to the maximum. Compare dates with a scalar MAX subquery to return all latest-date rows, or apply a deterministic ranking rule when exactly one latest record is needed. The same tie issue arises for maximum prices.
Several MAX expressions in one SELECT are independent summaries. MAX(amount) and MAX(created_on) can come from different records; placing them side by side does not describe one greatest sale. Avoid using this arrangement as a substitute for sorting or ranking. For text values, collation establishes what largest means. A code that contains digits is not necessarily a number, and the alphabetically largest code is not always the newest or highest numeric code. Choose types and ordering rules that match the business meaning.
MySQL, PostgreSQL, SQL Server and SQLite
Aggregate MAX is portable across these four engines. SQLite’s multiple-argument scalar max(...) is a separate form that should not be confused with the aggregate. Dates should use an appropriate representation: ISO-formatted text dates in SQLite sort coherently when the format is consistent, whereas arbitrary display strings do not.
Check the engine-specific syntax and version requirements in PostgreSQL MAX aggregate.
Practice task and worked solution
Find every sale whose amount equals the largest known amount. Return id and amount, sorted by id.
Try the task before reading its worked solution. The supplied rows make the expected answer checkable by hand.
SELECT id,amount FROM sales
WHERE amount = (SELECT MAX(amount) FROM sales)
ORDER BY id;id | amount
102 | 30The scalar subquery returns thirty. The outer predicate compares each sale amount with that value, keeping sale 102. If another sale were thirty, both would appear. NULL does not equal the known maximum and therefore does not enter the result.
Compare MAX(amount) with MAX(created_on): the first is thirty and the second is February 3. Read their source rows to show that the values come from different transactions. Restrict to paid status and predict a maximum amount of twenty, then return every paid sale equal to that maximum to observe the two tied real records.
SQL MAX Function: Largest Values, Dates and Grouped Results Syntax
MAX()
SELECT MAX(amount) AS largest_amount FROM sales;SQL MAX Function: Largest Values, Dates and Grouped Results Summary
MAX(column)returns the largest non-NULLvalue, orNULLwhen there's no known value.MAX(created_on)finds the latest date, which is a common way to see when something last happened.- Several
MAXcalls in one query are independent:MAX(amount)andMAX(created_on)may come from different rows. - To get the whole latest or largest row, filter with a subquery or rank rows with
ROW_NUMBER(). - Text maxima follow the collation, and dates stored as text only order correctly in
YYYY-MM-DDform.
SQL MAX Function: Largest Values, Dates and Grouped Results Examples
Each example shows the code, the output it produces and what each part does.
The largest known sale amount
The known amounts are ten, thirty, twenty, twenty and five. Thirty is the largest. The output is one numeric summary and does not claim that any other selected value belongs to sale 102.
SELECT MAX(amount) AS largest_amount FROM sales;largest_amount
30Common SQL MAX Function: Largest Values, Dates and Grouped Results Mistakes
Combining independent maxima as one row
SELECT MAX(amount),MAX(created_on) does not select a single sale. The amount thirty comes from sale 102, while the latest date belongs to sale 106. If the report needs the latest sale and its amount, rank or filter actual sale rows instead of combining independent maxima.
SQL MAX Function: Largest Values, Dates and Grouped Results in Real Projects
Highest sale per status in monitoring
A monitoring report can compare the highest sale amount in each status category. It should distinguish the biggest individual purchase from total revenue. If a category has no known amounts, retaining NULL lets the report show that data is unavailable rather than suggesting a zero-value maximum.
A latest-date measure and a highest-amount measure are independent unless the query explicitly selects one source row. Use separate labels when reporting independent maxima. When a latest-record view needs other fields, rank rows by the approved date-and-key rule so all selected columns come from the same chosen transaction.
SQL MAX Function: Largest Values, Dates and Grouped Results FAQ
Does MAX ignore NULL?
Yes. MAX skips NULL values, and it returns NULL if there is no known input, for example when a WHERE filter leaves no rows. Use COALESCE(MAX(amount), 0) only if zero is the correct answer for "no sales".
Can MAX find the newest row?
It can find the newest date value. Retrieving the row needs an additional selection rule and a decision about ties, such as WHERE created_on = (SELECT MAX(created_on) FROM sales) for all rows on that date or ORDER BY created_on DESC, id DESC LIMIT 1 for one.
Is the maximum text value portable?
The operation exists everywhere, but collation and the stored representation determine text ordering. In a case-sensitive binary collation, lowercase letters sort after capitals, so MAX of 'apple' and 'Banana' is 'apple'; a case-insensitive collation gives 'Banana'.
How do I find each customer's latest sale?
Group to find each customer's latest date, then join back, or rank the rows: ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY created_on DESC, id DESC) and keep row number 1. The window version handles ties in a controlled way.
What is the difference between MAX and ORDER BY ... LIMIT 1?
MAX(amount) returns only the largest value. ORDER BY amount DESC LIMIT 1 returns a whole row, and with an index on the column both are fast. Use MAX for the value in a summary, and the ordered limit when you need the row's other columns.
SQL MAX Function: Largest Values, Dates and Grouped Results Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Which sale rows are returned by the maximum-amount comparison?
SQL MAX Function: Largest Values, Dates and Grouped Results Quiz
2 questions to check what you learned.
What is the difference between MAX and SUM?
- MAX adds values while SUM chooses the largest
- MAX chooses the largest value; SUM adds the known values
- MAX and SUM both return the same total whenever NULL is present
Do MAX(amount) and MAX(created_on) necessarily describe one sale?
- Yes, both maxima necessarily select fields from one source row
- Yes, but only when no GROUP BY is written
- No, the independent maxima can come from different records