SQL Multiple Aggregates
List several aggregate functions in the same SELECT — each one is computed independently, over the same groups, in a single pass.
What & Why
Nothing stops a query from computing several different summaries at once — COUNT, SUM, AVG, MIN, and MAX can all appear side by side in the same SELECT list. Postgres computes each one independently, but all of them share the exact same groups formed by GROUP BY — so there's no cost to asking for four summaries instead of one; it's still a single pass over the data.
See How It Works
Marketing wants campaign count, total spend, and average spend together.
| id | name | channel | spend | start_date | end_date | status | target_segment |
|---|---|---|---|---|---|---|---|
| 1 | Spring Launch | google_ads | 55000.00 | 2024-01-15 | 2024-03-31 | active | smb |
| 2 | Retention Webinar | 45000.00 | 2024-02-10 | 2024-04-15 | active | enterprise | |
| 3 | Finance Retargeting | 50000.00 | 2024-03-12 | 2024-05-31 | active | enterprise | |
| 4 | Enterprise Search | google_ads | 60000.00 | 2024-04-01 | 2024-06-30 | active | enterprise |
SELECT
channel,
COUNT(*) AS campaigns,
SUM(spend) AS total_spend,
ROUND(AVG(spend), 2) AS avg_spend
FROM marketing.campaigns
GROUP BY channel
ORDER BY total_spend DESC, channel;| channel | campaigns | total_spend | avg_spend |
|---|---|---|---|
| google_ads | 2 | 115000.00 | 57500.00 |
| 1 | 50000.00 | 50000.00 | |
| 1 | 45000.00 | 45000.00 |
Every result row summarizes one real campaign channel.
Practice this concept
Marketing wants campaign count, total spend, and average spend together.
marketingPrefix tables with marketing.table_name.
channelcampaignstotal_spendavg_spendmarketing.campaigns| Column | Type |
|---|---|
| id | integer |
| name | text |
| channel | text |
| spend | numeric |
| start_date | date |
| end_date | date |
| status | text |
| target_segment | text |
| legacy_id | text |
Sign up free to try it on a real business scenario