Aggregates and Group By
Summarize rows with aggregates and grouping. Results appear in the same fence: same-line -- comments when short, multiline -- blocks below the sample when not.
Busca en todas las páginas de la documentación
Summarize rows with aggregates and grouping. Results appear in the same fence: same-line -- comments when short, multiline -- blocks below the sample when not.
One output row per group key.
SELECT user_id, count(*) AS n
FROM orders
GROUP BY user_id;
-- n per userFilter groups after aggregation.
SELECT user_id, sum(total) AS spend
FROM orders
GROUP BY user_id
HAVING sum(total) > 1000;
-- big spendersCount unique values.
SELECT count(DISTINCT user_id) FROM orders;
-- unique buyersConditional aggregates without CASE soup.
SELECT
count(*) AS all_rows,
count(*) FILTER (WHERE status = 'open') AS open_rows
FROM orders;
-- all_rows / open_rowsConcatenate strings per group.
SELECT user_id, string_agg(tag, ',' ORDER BY tag) AS tags
FROM user_tags
GROUP BY user_id;
-- tags: a,b,cStandard numeric aggregates.
SELECT avg(total), sum(total), min(total), max(total)
FROM orders
WHERE created_at >= CURRENT_DATE - 30;
-- last 30 days statsGroup on expressions or ordinals carefully.
SELECT date_trunc('day', created_at) AS day, count(*)
FROM events
GROUP BY 1
ORDER BY 1;
-- daily countsMultiple groupings in one pass.
SELECT region, product, sum(sales)
FROM t
GROUP BY GROUPING SETS ((region), (product), ());
-- region totals, product totals, grand totalHierarchy of subtotals.
SELECT year, month, sum(n)
FROM sales
GROUP BY ROLLUP (year, month);
-- month, year, grandAggregate booleans.
SELECT user_id, bool_and(ok) AS all_ok
FROM checks
GROUP BY user_id;
-- all_ok true if every check passedCollect values into an array.
SELECT user_id, array_agg(order_id ORDER BY created_at) AS order_ids
FROM orders
GROUP BY user_id;
-- order_ids: {1,2,3}Continuous percentile (ordered-set aggregate).
SELECT percentile_cont(0.5) WITHIN GROUP (ORDER BY latency_ms)
FROM requests;
-- median latencycount(*) counts rows; count(col) skips NULL.
SELECT count(*), count(email) FROM users;
-- second ignores null emailsPrefer GROUP BY for aggregates; DISTINCT ON for pick-one-row.
SELECT user_id, max(created_at) AS last_seen
FROM events
GROUP BY user_id;WHERE reduces input rows; HAVING reduces groups.
SELECT user_id, count(*)
FROM orders
WHERE status = 'paid'
GROUP BY user_id
HAVING count(*) >= 3;
-- repeat paid buyersStack versions: PostgreSQL 18.4 (stable 18, maintenance 17) · pgvector 0.8+
Revisado por Chris St. John·Última actualización: 18 jul 2026