1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

読んで欲しい人

  • 「GROUP BY」クエリを指定した時に、何が起きているのかイマイチイメージが掴めない...
  • 「GROUP BY」で取得する時にERROR 1055 (42000): Expression xx of SELECT list is not in GROUP BY clause and contains nonaggregated column 'xxx' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_byみたいなエラーが出るんですけど。

っていう人はぜひ読んでみてください!

※ この記事では MySQL を使用することを想定しています。

GROUP BY を使用するユースケース

例えば、以下のような DDL で定義されるテーブルがあるとします。

-- 売上テーブル
CREATE TABLE sales (
    id INT PRIMARY KEY,
    product_name VARCHAR(50),
    category VARCHAR(20),
    price INT,
    quantity INT,
    region VARCHAR(10)
);

そして、このテーブルには以下のようなレコードが挿入されているとします。

id product_name category price quantity region
1 ノート PC 電子機器 80000 2 東京
2 マウス 電子機器 3000 5 大阪
3 小説 A 書籍 1500 3 東京
4 キーボード 電子機器 8000 1 名古屋
5 参考書 B 書籍 2800 2 大阪
6 デスク 家具 25000 1 東京
7 チェア 家具 15000 2 福岡
8 タブレット 電子機器 45000 1 大阪
9 雑誌 C 書籍 800 4 名古屋
10 ソファ 家具 60000 1 福岡

ここで、あなたは「各カテゴリごとの売上合計を教えて欲しい」と注文を受けました。ここでGROUP BYクエリの出番です。

GROUP BYクエリを使用すると、指定した列ごと(今回の場合はcategoryごと)にレコードのグループを編成し、そのレコードグループに対して集約関数を適用させて値を計算できます。

例えば、

SELECT xxx FROM sales GROUP BY category;

のようにcategory列でGROUP BYクエリを実行した結果、以下のようにレコードグループを編成することができます。(あくまでイメージ)

category = "電子機器"のグループ

id product_name category price quantity region
1 ノート PC 電子機器 80000 2 東京
2 マウス 電子機器 3000 5 大阪
4 キーボード 電子機器 8000 1 名古屋
8 タブレット 電子機器 45000 1 大阪

category = "書籍"のグループ

id product_name category price quantity region
3 小説 A 書籍 1500 3 東京
5 参考書 B 書籍 2800 2 大阪
9 雑誌 C 書籍 800 4 名古屋

category = "家具"のグループ

id product_name category price quantity region
6 デスク 家具 25000 1 東京
7 チェア 家具 15000 2 福岡
10 ソファ 家具 60000 1 福岡

そしてSELECT句の中で、各レコードグループに対して集約関数を適用させることができます。
例えば、

SELECT category, SUM(price * quantity) as total_sales FROM sales GROUP BY category;

とした場合、各レコードグループごとに以下の値を引っ張ってきてくれます。

  • 各レコードグループのcategory
  • 各レコードグループの中の全レコードのprice * quantitiy合計値

なので結果は以下のようになります。

category total_sales
電子機器 228000
書籍 13300
家具 115000

GROUP BYのだいたいのイメージは掴めましたか?

GROUP BY を使用すると気に注意すべき点

GROUP BYを使用する時に注意しないといけない点の一つとして、GROUP BYを使用する場合、SELECT句で指定できるものは、以下のものに限られます。

  • GROUP BYで指定される列
  • 集約関数の計算結果

これは冒頭のERROR 1055 (42000): Expression xx of SELECT list is not in GROUP BY clause and contains nonaggregated column 'xxx' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_byのエラーに関わってきます。

例えば以下のようなsqlを書いた場合、このエラーが返ってきます。

SELECT product_name, category, SUM(price * quantity) as total_sales FROM sales GROUP BY category;

返ってくるエラー

ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'sandbox.sales.product_name' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

これは一体何が起こっているのでしょうか?
categoryGROUP BYをした場合に編成されるレコードグループの一つをもう一度みてみましょう。

category = "書籍"のグループ

id product_name category price quantity region
3 小説 A 書籍 1500 3 東京
5 参考書 B 書籍 2800 2 大阪
9 雑誌 C 書籍 800 4 名古屋

このグループでは、categoryGROUP BYで指定された列であり、各レコードグループごとに一意であることが保証されています。

一方で、product_nameに関しては、小説 A参考書 B雑誌 Cの3つが存在します。

このproduct_nameに対して SELECTを当てたとしても結局どのレコード(id = 3, 5, 9)のproduct_nameをとってこれば良いかMySQLはわからないため、エラーになってしまいます。

これはidregionについても同様と言えます。また、今回はSUM(price * quantity) as total_salesという形で集約関数を使用して取得できていますが、price, quantityも集約関数を使わずにその列だけで取得しようとする場合、同様のエラー発生がします。

GROUP BYを使用する際は、この点に注意しましょう!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?