E051-02, “GROUP BY clause”


BigQueryDb2 (LUW)DuckDBH2MariaDBMySQLOracle DBPostgreSQLSQL ServerSQLite20162018202020222024✓ 3.21.0 - 3.51.0✓ 2017 - 2025✓ 10 - 18✓ 18c - 23.26.1✓ 8.0.11 - 9.6.0✓ 10.3 - 12.2.2⚡ 1.4.192 - 2.4.240a✓ 1.0.0 - 1.4.0✓ 11.1 - 12.1.3⚡ 2.0a✓ 2.0
  1. ⚡Incompatible access to select names possible

Extensions

The group by clause has a number of widely available extensions. First of all it must be noted that a standard SQL group by clause accepts column names only—expressions are not allowed. All tests systems accept expressions nevertheless ①. In that case it is handy if the group by clause can also refer to columns declared in the corresponding select clause ②. This extension is also widely available but might come with a danger:

SELECT b AS a
  FROM (VALUES (1, 1), (1, 2)) t(a,b)
 GROUP BY a

The column a defined in the select clause is not visible to the group by clause in standard SQL. Therefore, the column name a in the group by clause refers to the column a of the table t so that the query produces a single row. Some of the systems that make the columns of the select clause visible in group by give precedence to select list columns over from clause columns. Such systems produce an incompatible result with two rows.

An entirely different option to refer to select columns from the group by clause is by using a unsigned integer that is interpreted as the 1-based column number of the select clause ③. While this does not introduce dangerous ambiguity,0 there is the risk that changing the select clause also changes the meaning of the group by clause in an unintended way. The bigger the query is—actually, the further the select and group by clauses are apart—, the higher the risk. The same risk applies to the group by all variant ④, which is probably part of the next SQL standard.

BigQuery 2026-02-12abDb2 (LUW) 12.1.3DuckDB 1.4.0cH2 2.4.240bMariaDB 12.2.2MySQL 9.6.0aOracle DB 23.26.1dPostgreSQL 18SQL Server 2025SQLite 3.51.0Expressions in Group BySelect-Names in Group By ②Group By <unsigned integer> ③group by all
  1. Only if the complete select entry equals the group by entry. I.e. not:
    SELECT a + b FROM ... GROUP BY a, b
  2. Select clause names take precedence over from clause columns
  3. Cannot mix aggregates with non-aggregated columns: a + count(*)
  4. Removes the group by all clause if it leads to an error that does not happen without group by clause
Standard Features
Non-standard Features

Normative References

E051-02, “GROUP BY clause” is a mandatory feature in ISO/IEC 9075-2:2023. The functionality was required in ANSI X3.135-1989 already.

You can’t catch up on 20 years of SQL evolution in one day. Subscribe the newsletter via E-Mail, Bluesky or RSS to gradually catch up and to keep modern-⁠sql.com on your radar.

About the Author

Photo of Markus Winand

Markus Winand provides insights into SQL and shows how different systems support it at modern-sql.com. Previously he made use-the-index-luke.com, which is still actively maintained. Markus can be hired as trainer, speaker and consultant via winand.at.

Buy the Book

Cover of “SQL Performance Explained”: Squirrel running on grass

The essence of SQL tuning in 200 pages

Buy now!
(paperback and/or PDF)

Paperback also available at Amazon.com.

Hire Markus

Markus offers SQL training and consulting for developers working at companies of all sizes.
Learn more »

Footnotes

  1. There is the ambiguity that the <unsigned integer> is understood as an expression. But I do not see any real-world case that could bit hit by that.

Connect with Markus Winand

Subscribe mailinglistsSubscribe the RSS feedMarkus Winand on LinkedInMarkus Winand on XINGMarkus Winand on MastodonMarkus Winand on Bluesky
Copyright 2015-2026 Markus Winand. All righs reserved.
Legal | Contact | NO WARRANTY | Trademarks | Privacy and GDPR