📘

GROUP BY句にPRIMARY KEYを指定する

2022/12/11に公開

何げなく使っている機能やコードで、よく考えると「あれ?」って思うことがたまにあります。
最近、ふと疑問に思った「GROUP BY句にPRIMARY KEYを指定した」場合の挙動について、記事にしたいと思います。

本題

結論から言ってしまうと、GROUP BY句にPRIMARY KEYを指定していれば、それ他の列は GROUP BY 句に指定しなくても、SELECTできます。
※私は主にPostgreSQLを使用しているので、他のRDBMSが同様かは把握していないです。※PostgreSQLでは 9.1から入った機能みたいです。

一応👇にドキュメントの引用を貼っておきます。

productsテーブルが、例えば、product_idが主キーであるように設定されている場合、nameとprice列は製品ID(product_id)に関数依存しており、このため製品IDグループそれぞれに対してどのnameとpriceの値を返すかに関するあいまいさがありません

余談

本題だけを書くと、GROUP BY句にPRIMARY KEYを指定する場面ってあまり無くない?と思われる方もいるかもしれないので、余談までに私が疑問に感じた場面を、ここからは書いていきます。

productテーブルとbugテーブルがあり、この二つのテーブルの関係が1対Nだったとします。
👇のようなテーブルを作成

CREATE TABLE products (
 id SERIAL PRIMARY KEY,
 name varchar(10) NOT NULL
);
CREATE TABLE bugs (
 id SERIAL PRIMARY KEY,
 product_id int references products(id) NOT NULL,
 name varchar(10) NOT NULL
);

この時にproductに紐づくbugの数を集計したいとします。
そのような場合にGROUP BY句にproductのPRIMARY KEY(products.id)を指定をする。SELECT句にはGROUP BY句に制定しなかった値(products.name)を指定して、集計をしたとします。
このようなユースケースでは本題に記載した機能を利用していることになります。
※今回の場合は、SELECT句にbugのnameを指定することはできないです。

SELECT products.id, products.name, COUNT(bugs.id) 
 FROM products
 LEFT OUTER JOIN bugs ON bugs.product_id = products.id
 GROUP BY products.id

上記のようなSQLを書いている時に、ふと「SELECT句にGROUP BY句に指定していない値を集計せずに書けるのなんでだっけ?」と疑問に思って、調べることにしたという経緯でした。

Discussion