max
Return the maximum value in a column — the go-to aggregate for peaks, latest timestamps, and largest orders.
Signature
max(x): TReturns
Same type as the input column (Nullable if the column is Nullable)
What it does
Returns the largest value across the rows in each group. The exact mirror of min. Works on numbers, dates, and strings, and skips NULLs.
max is one of the most common aggregate functions in ClickHouse analytics: it collapses a group of rows down to the single largest value. It works on any orderable type — numbers, DateTime, Date, and strings — so it covers peak latency, the most recent event timestamp, and the largest order in one function. max ignores NULLs, so a Nullable column returns the largest non-NULL value (or NULL if every row is NULL). It pairs naturally with min for range queries, and when you need the row *at* the maximum rather than just the value, reach for argMax instead.
Notes
- max ignores NULLs and returns the largest non-NULL value; it returns NULL only when every row in the group is NULL.
- max(created_at) gives you the latest timestamp, but not the other columns from that row — use argMax(other_col, created_at) to fetch the value at the maximum. hypequery exposes this natively as .argMax('other_col', 'created_at', 'alias').
- On a ReplacingMergeTree table, the argMax pattern (or .final()) is the standard way to pick the latest version of each key without paying for a full FINAL merge.
- max comes back typed by hypequery's generated schema — a max over a UInt64 column arrives as a string in JS, and a max over DateTime arrives as a string, matching ClickHouse's wire format.
Example SQL
max in ClickHouse SQL
TypeScript with hypequery
Use max in a typed TypeScript query
hypequery gives you a type-safe query builder for ClickHouse. The generated schema maps your ClickHouse columns to TypeScript types, and raw SQL expressions let you incorporate functions like max when you need them inside a builder query.
Common questions
What developers search for with max
Latest value per key in ClickHouse
max(created_at) finds the most recent timestamp per group, but to grab the row at that timestamp use argMax(status, created_at). hypequery exposes .argMax('status', 'created_at', 'latest_status') natively — the same idiom that deduplicates a ReplacingMergeTree.
Peak latency and largest order in TypeScript
Use .max('latency_ms', 'peak_latency') to get the worst latency per tenant, or .max('total', 'largest_order') for the biggest order. Results are fully typed from your generated schema.
max vs argMax in ClickHouse
max returns the largest value; argMax returns another column's value at the row where a given column is largest. Pick max for the number, argMax when you need the accompanying data.
FAQ
Frequently asked questions about max
What does max return in ClickHouse?
It returns the single largest value across the rows in each group, in the same type as the input column. It works on numbers, dates, and strings, and skips NULLs, returning NULL only when every row is NULL.
How do I get the row at the maximum, not just the value?
Use argMax instead of max: argMax(status, created_at) returns the status from the row with the largest created_at. In hypequery this is .argMax('status', 'created_at', 'latest_status').
How do I use max in hypequery?
Call the native .max(column, alias) aggregate on the query builder, for example .max('latency_ms', 'peak_latency'), then .groupBy(...) and .execute(). The result column is typed from your generated schema.
Next step
Use max in a type-safe TypeScript query
hypequery generates TypeScript types from your ClickHouse schema. Use max alongside the builder, and reach for raw SQL expressions when the function is not exposed as a dedicated helper.