📘
SQLのGroupBYの挙動について考える。
まえがき
SQLで集計する場合、GroupByを使うことが多いと思いますが、この挙動を把握していなくてハマったことがありました。
あるカラムに入っている値の一覧を重複なしで取り出して、それを画面に出そうとしているのに、どうしても重複が解消できないことがありました。
これについて解説していきます。
解説
テストデータとして以下を用意しました。
CREATE TABLE public.customer (
id serial4 NOT NULL,
"name" varchar NULL,
gender bpchar(1) NULL,
age int4 NULL
);
INSERT INTO public.customer
(id, "name", gender, age)
VALUES(nextval('customer_id_seq'::regclass), 'Lloyd', 'M', 17)
,(nextval('customer_id_seq'::regclass), 'Collet ', 'F', 16)
,(nextval('customer_id_seq'::regclass), 'Genius ', 'M', 12)
,(nextval('customer_id_seq'::regclass), 'Refill ', 'F', 23)
,(nextval('customer_id_seq'::regclass), 'Shihna ', 'F', 19)
,(nextval('customer_id_seq'::regclass), 'Zelos ', 'M', 22)
,(nextval('customer_id_seq'::regclass), 'Presea ', 'F', 12)
,(nextval('customer_id_seq'::regclass), 'Regal ', 'M', 33)
,(nextval('customer_id_seq'::regclass), 'Kratos ', 'M', 28)
;
そうするとこういう原本ができます。
SELECT c.* FROM public.customer AS c
id|name |gender|age|
--+---------+------+---+
1|Lloyd |M | 17|
2|Collet |F | 16|
3|Genius |M | 12|
4|Refill |F | 23|
5|Shihna |F | 19|
6|Zelos |M | 22|
7|Presea |F | 12|
8|Regal |M | 33|
9|Kratos |M | 28|
ここから、このテーブルに入っている年齢の一覧を取得したいと思います。
なので、年齢でグルピーングしてみます。
SELECT age
FROM public.customer
GROUP BY age
ORDER BY age ASC
;
age|
---+
12|
16|
17|
19|
22|
23|
28|
33|
問題ないですね。
年齢の一覧が重複なくとれています。
今度は年齢も集計条件に加えてみます。
SELECT age
FROM public.customer
GROUP BY age,gender
ORDER BY age ASC
;
age|
---+
12|
12|
16|
17|
19|
22|
23|
28|
33|
あれ!?「12」が二つある??
という具合です。
これは取得する列を増やせば明白なのですが、
SELECT age,gender,count(*)
FROM public.customer
GROUP BY age,gender
ORDER BY age ASC
;
age|gender|count|
---+------+-----+
12|M | 1|
12|F | 1|
16|F | 1|
17|M | 1|
19|F | 1|
22|M | 1|
23|F | 1|
28|M | 1|
33|M | 1|
こうなってるわけです。
12歳の男性が1人、12歳の女性が1人、というレコードに分かれたから2行になってたんですね。
終わりに
今回は単純な取得なので確認しやすくしていますが、実際に私がハマっていたときは、この結果をサブクエリとしてメインクエリのIN句に使ったりとかだったので、大変でした。
分かってしまえば当たり前ですが、グルーピングの条件を詳細にしていけばレコード数は増えます。
エクスプローラでフォルダの中を整理してサブフォルダつくっていうと、フォルダ総数は増えるのとにているかもしれません。
株式会社ONE WEDGE
【Serverlessで世の中をもっと楽しく】 ONE WEDGEはServerlessシステム開発を中核技術としてWeb系システム開発、AWS/GCPを利用した業務システム・サービス開発、PWAを用いたモバイル開発、Alexaスキル開発など、元気と技術力を武器にお客様に真摯に向き合う価値創造企業です。
Discussion