GROUP BY句にPRIMARY KEYを指定する
何げなく使っている機能やコードで、よく考えると「あれ?」って思うことがたまにあります。
最近、ふと疑問に思った「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