1年半くらい前に、こんな記事を書きました。
MySQLのGroup By - 職業プログラマの休日出勤
MySQLのこのような仕様のせい(?)で、バグの発見が遅くなってしまった、という話です。
先日、SQLWorld★大阪 #21 というイベントに参加してきましたが、そこで得た情報の一つに、PostgreSQLのGroupByにも上記のMySQLのやつと似たようなのがある、というものがありました。
この記事は、その「不思議な」Group Byの動作を検証するものです。
テストデータ
CREATE TABLE test20140127 ( pkey1 integer NOT NULL, pkey2 character varying(10) NOT NULL, data1 text, CONSTRAINT pkey_of_test20140126 PRIMARY KEY (pkey1, pkey2) ) WITH ( OIDS=TRUE ); INSERT INTO test20140127 VALUES(1, 'foo', 'bar'); INSERT INTO test20140127 VALUES(2, 'foo', 'barr'); INSERT INTO test20140127 VALUES(2, 'foo2', 'barrr'); INSERT INTO test20140127 VALUES(3, 'x', 'brrrrrrrr');
明らかにダメなクエリ
select * from test20140127 group by data1
こんなクエリがエラーになることは、皆さんも容易に想像できるかと思います。
ERROR: 列"test20140127.pkey1"はGROUP BY句で出現しなければならないか、集約関数内で使用しなければなりません LINE 1: select * ^
ほら。
ぁゃιぃクエリ
さて、ここからが本題です。
次のクエリはどうなるでしょうか?
select * from test20140127 group by pkey1, pkey2
このクエリ、なんと正常に実行できるのです。
確かに、単一テーブルへの select 文で、 primary key で group by したら、それは問題無さそうです。
その通りなのですが、今まで考えたこともありませんでした。
この機能(?)はPostgreSQLの9.1で入ったそうなのですが、何故こんなぁゃιぃ機能をわざと入れたのか疑問に思っていました。
気になって9.1のReleaseNoteを見てみると、
Allow non-GROUP BY columns in the query target list when the primary key is specified in the GROUP BY clause (Peter Eisentraut)
http://www.postgresql.org/docs/9.1/interactive/release-9-1.html
The SQL standard allows this behavior, and because of the primary key, the result is unambiguous.
ということでした。SQL標準に規定されているんです。知りませんでした。
この機能を積極的に使うといったことは、実務ではまずあり得ないでしょうけれども、頭の片隅には置いておきたいものです。
検証環境
PostgreSQL 9.3.2
- 作者: 鈴木啓修
- 出版社/メーカー: 技術評論社
- 発売日: 2012/11/16
- メディア: 単行本(ソフトカバー)
- 購入: 2人 クリック: 14回
- この商品を含むブログ (5件) を見る