patternsqlModerate
Why can I select all fields when grouping by primary key but not when grouping by another column
Viewed 0 times
whycanprimaryallgroupingfieldsbutcolumnanotherwhen
Problem
How is this a valid statement (where id is the primary key of the table):
and this is not:
ERROR: column "pgluser.id" must appear in the GROUP BY clause or be used in an aggregate function
Fiddle.
The question is why is the first a legal query, ie why grouping by primary key is valid?
select * from table group by id ;and this is not:
select * from table group by name ;ERROR: column "pgluser.id" must appear in the GROUP BY clause or be used in an aggregate function
Fiddle.
The question is why is the first a legal query, ie why grouping by primary key is valid?
Solution
id is a primary key.As far as I remember, this is actually a legal query according to ANSI/ISO SQL.
Grouping by primary key results in a single record in each group which is logically the same as not grouping at all / grouping by all columns, therefore we can select all other columns.
create table t (id int primary key,c1 int,c2 int)
insert into t (id,c1,c2) values (1,2,3),(4,5,6);
select * from t group by id;+----+----+----+
| id | c1 | c2 |
+----+----+----+
| 1 | 2 | 3 |
+----+----+----+
| 4 | 5 | 6 |
+----+----+----+Reference given by @a_horse_with_no_name
https://www.postgresql.org/docs/current/static/sql-select.html#SQL-GROUPBY
When GROUP BY is present, or any aggregate functions are present, it
is not valid for the SELECT list expressions to refer to ungrouped
columns except within aggregate functions or when the ungrouped column
is functionally dependent on the grouped columns, since there would
otherwise be more than one possible value to return for an ungrouped
column. A functional dependency exists if the grouped columns (or a
subset thereof) are the primary key of the table containing the
ungrouped column.
While logically we would expect UNIQUE NOT NULL to follow the same behaviour, it applies only for PK (as described in the documentation)
create table t (id int unique not null,c1 int,c2 int);
insert into t (id,c1,c2) values (1,2,3),(4,5,6);
select * from t group by id;[Code: 0, SQL State: 42803] ERROR: column "t.c1" must appear in the
GROUP BY clause or be used in an aggregate function
Code Snippets
create table t (id int primary key,c1 int,c2 int)
insert into t (id,c1,c2) values (1,2,3),(4,5,6);
select * from t group by id;+----+----+----+
| id | c1 | c2 |
+----+----+----+
| 1 | 2 | 3 |
+----+----+----+
| 4 | 5 | 6 |
+----+----+----+create table t (id int unique not null,c1 int,c2 int);
insert into t (id,c1,c2) values (1,2,3),(4,5,6);
select * from t group by id;Context
StackExchange Database Administrators Q#158015, answer score: 11
Revisions (0)
No revisions yet.