Applies to: ✅ Data 360 SQL ✅ Tableau Hyper API
Returns the <value> from the row whose <key> is smallest among all rows in the aggregate (or within each group when used with GROUP BY).
Syntax
min_by(<value>, <key>)
Arguments
Required
<value>: Any expression whose result is returned when its row wins the comparison. The aggregate result type matches this expression’s type.<key>: The expressionMIN-BYuses to order rows. The type must support comparison.
Returns
The <value> from the row with the minimum <key> among considered rows.
Null handling:
- If the aggregate has no input rows (empty table or empty group), the result is
NULL. - If every row has a
NULLkey, those rows are skipped; if no row has a non-NULLkey, the result isNULL. - If the winning row’s
<value>isNULL, the result isNULL(the key still determines which row wins).
Tie breaking:
When multiple rows share the same minimum key, one of the tied <value> results is returned; which tied row wins is implementation-dependent.
Considerations
- Exactly two arguments are required (
<value>,<key>). Calls with one argument or more than two arguments raise a syntax error. - You can combine
min_bywith other aggregates,GROUP BY,HAVING, subqueries, and expressions in the arguments (for example,max_by(upper(name), score * 2)). min_byonly supports a single value to sort on. To sort using multiple sort criteria, use FIRST_VALUE WITHIN GROUP.- Rows with a
NULL<key>are ignored when searching for the minimum key.
Examples
Lowest scorer by score
Returns the name and score from the row with the lowest score.
SELECT min_by(name, score) RESPECT NULLS, min(score) AS low_scorer
FROM (
VALUES
(1, 'Alice', 85),
(2, 'Bob', 92),
(3, 'Charlie', 78),
(4, 'David', 95),
(5, 'Eve', 88)
) AS t(id, name, score);
Returns 'Charlie'.
NULL keys ignored
With keys 5, NULL, 10, and 15, the minimum non-NULL key is 5, so the result is that row’s value.
SELECT min_by(value, key_val) AS result
FROM (
VALUES
(10, 5),
(20, NULL::int),
(30, 10),
(NULL::int, 15)
) AS t(value, key_val);
Returns 10.
Worst product per region by revenue
SELECT region, min_by(product, revenue) AS worst_product
FROM (
VALUES
('North', 'A', 100),
('North', 'B', 150),
('South', 'A', 200),
('South', 'B', 120)
) AS sales(region, product, revenue)
GROUP BY region;
Returns one row per region. For example North / 'A' and South / 'B'.