min_ by
On this page
Returns a value from the row with the minimum comparison key.
Syntax
min_by(<value>, <key>)Arguments
| Argument | Type | Description |
|---|---|---|
<value> | Any type | Expression to return from the selected row. May be NULL. |
<key> | Any type except any | Expression used to select the row. NULL keys are ignored. |
Returns
Returns the same type as <value>. Returns NULL if there is no non-NULL key. If keys tie, any tied row may be selected.
Examples
Keep the details of the fastest request
Find the fastest request per service and retain its ID and status together in one object.
VALUES
('checkout', 'req-101', 200, 95), ('checkout', 'req-102', 504, 1200),
('catalog', 'req-201', 200, 25), ('catalog', 'req-202', 200, 140)
SELECT $0 AS service, $1 AS request_id, $2 AS status, $3 AS latency_ms
GROUP BY service
AGGREGATE min_by({'request_id': request_id, 'status': status}, latency_ms) AS request
ORDER BY service+----------+---------------------------------------+
| service | request |
+----------+---------------------------------------+
| catalog | {"request_id":"req-201","status":200} |
| checkout | {"request_id":"req-101","status":200} |
+----------+---------------------------------------+Find the first acquisition channel
Choose the channel on the earliest event for each buyer, even when events arrive out of order.
VALUES
('buyer-17', '2026-06-01T10:05:00Z', 'email'),
('buyer-17', '2026-06-01T09:00:00Z', 'search'),
('buyer-42', '2026-06-01T11:00:00Z', 'referral')
SELECT $0 AS buyer_id, $1::timestamp AS event_time, $2 AS channel
GROUP BY buyer_id
AGGREGATE min_by(channel, event_time) AS first_channel
ORDER BY buyer_id+----------+---------------+
| buyer_id | first_channel |
+----------+---------------+
| buyer-17 | search |
| buyer-42 | referral |
+----------+---------------+