web-dev-qa-db-ja.com

主キーでグループ化するときにすべてのフィールドを選択できるが、別の列でグループ化するときはなぜできないのか

これはどのように有効なステートメントですか(idはテーブルの主キーです)。

select * from table group by id ;

そしてこれは:

select * from table group by name ;

エラー:列 "pgluser.id"はGROUP BY句に出現するか、集計関数で使用する必要があります

フィドル

問題は、なぜ最初のクエリが正当なクエリなのか、つまり主キーによるグループ化がなぜ有効なのかということです。

4
Sachin Verma

idは主キーです。
私が覚えている限り、これは実際にはANSI/ISO SQLに基づく正当なクエリです。
主キーでグループ化すると、各グループに単一のレコードが作成されます。これは、まったくグループ化しない/すべての列でグループ化するのと論理的に同じなので、他のすべての列を選択できます。

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  |
+----+----+----+

@a_horse_with_no_nameによる参照

https://www.postgresql.org/docs/current/static/sql-select.html#SQL-GROUPBY

GROUP BYが存在する場合、または集約関数が存在する場合、集約関数内、またはグループ化されていない列がグループ化された列に機能的に依存している場合を除いて、SELECTリスト式がグループ化されていない列を参照することは無効です。グループ化されていない列に対して返す可能性のある1つの値よりも多くなります。 グループ化された列(またはそのサブセット)がグループ化されていない列を含むテーブルの主キーである場合、機能的な依存関係が存在します。


論理的にはUNIQUE NOT NULLが同じ動作に従うことを期待しますが、PKにのみ適用されます(ドキュメントで説明されています)。

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;

[コード:0、SQL状態:42803]エラー:列 "t.c1"はGROUP BY句に出現するか、集計関数で使用する必要があります

その理由は次のとおりだと思います:

ここではidが主キーであり、主キーによるグループ化はgroup by *と似ています。だからそれはちょうどに似ています

select * from table group by *

大丈夫です。

0
Sachin Verma