SQL GROUP BY ALL and ORDER BY ALL
GROUP BY ALL groups by every column in the SELECT list that isn't an aggregate, so you never repeat them. ORDER BY ALL sorts by every column, left to right. Both are DuckDB shortcuts.
GROUP BY ALL tells DuckDB to group by every expression in the
SELECT list that isn't an aggregate. You write the columns
once, and the GROUP BY can't fall out of step with them.
ORDER BY ALL sorts by every column, left to right.
select category_id,
count(*) as products,
round(avg(price), 2) as avg_price
from products
group by all
order by all
That returns one row per category, sorted by category_id. The
portable form lists the column again:
group by category_id order by category_id.
When to use it
- Exploring. Adding or removing a grouping column means editing one line instead of two.
- Grouping by an expression, such as
upper(status)or aCASE, where repeating it inGROUP BYinvites a typo. - Queries that only DuckDB will run. Code that has to run on PostgreSQL, MySQL, or SQL Server needs the columns listed.
What GROUP BY ALL picks
Every SELECT expression that contains no aggregate becomes a
grouping key, columns from a join included:
select c.category_name,
count(*) as products
from products as p
join categories as c on c.category_id = p.category_id
group by all
order by products desc, c.category_name
A window function can't be grouped on: a SELECT list with
sum(amount) over () next to plain columns fails with
Cannot group on a window clause.
ORDER BY ALL
ORDER BY ALL sorts by the first column, then the second, and so
on. ORDER BY ALL DESC reverses every column. It doesn't know
which column you care about, so "the states with the most customers" still
needs the sort spelled out:
select state,
count(*) as customers
from customers
group by all
order by customers desc, state
With order by all instead, PA, which has the most customers
(6), would sit fifth, between OR and TX.
What can go wrong
- Adding a column changes the grain. With an explicit
GROUP BY, a newSELECTcolumn that isn't grouped is an error. WithGROUP BY ALLit silently becomes another key. Below, addingdiscontinuedto look at it splits category 8 into two rows, and addingproduct_namewould turn 8 rows into 24 rows of 1. -
ORDER BY ALLisn't "order by the metric". It sorts by the leftmost column first. - SQL Server's
GROUP BY ALLis something else. It's a deprecated form, followed by a column list, that keeps groups theWHEREclause filtered out, withNULLaggregates.
select category_id,
discontinued,
count(*) as products
from products
group by all
order by all How other databases differ
| Engine | GROUP BY ALL | Instead |
|---|---|---|
| DuckDB | Yes, and ORDER BY ALL | |
| Snowflake, Databricks, ClickHouse | Yes | |
| PostgreSQL, MySQL, SQLite | No |
List the columns, or their positions: group by 1, 2 |
| SQL Server | A different, deprecated feature |
List the columns; GROUP BY doesn't take positions
|
group by 1 counts positions in the SELECT list.
It's shorter than naming the columns and runs in more engines than
GROUP BY ALL, but reordering the SELECT list
quietly changes what it groups by.
Related
Keep one whole row per group, chosen by ORDER BY.
Leave out, replace, or pick columns by pattern.
Random rows, repeatable with a seed.
COUNT, SUM, AVG, MIN, MAX, GROUP BY, and HAVING.