スポンサーリンク

【応用情報技術者試験】DISTINCTとGROUP BY

DISTINCTは「同じ値の組合せを一度だけ表示したい」とき、GROUP BYは「同じ値の行をまとめたい」ときに使います。似た結果になることもありますが、まず目的から区別しましょう。

この記事で違いとビューでの使い方を確認し、集計条件の使い分けは末尾の無料noteで例題に進めます。

1.一覧を重複なく出すならDISTINCT

SELECTで指定した列の値の組合せが同じ行を、結果から重複なく表示します。元の表の行を削除する命令ではありません。

SELECT DISTINCT 部署
FROM 売上表;

営業の行が複数あっても、部署の一覧には営業を一度だけ表示します。複数列を指定した場合は、その組合せで重複を判断します。

2.部署ごとの合計を出すならGROUP BY

DISTINCTと、WHERE・GROUP BY・HAVINGの役割の違い
DISTINCTと、WHERE・GROUP BY・HAVINGの役割の違い
SELECT 部署, SUM(売上) AS 合計
FROM 売上表
GROUP BY 部署;

同じ部署の行をグループ化し、SUMで合計します。GROUP BYだけでも同じ値をまとめられますが、集計関数と組み合わせると「グループごとの計算」という目的が分かりやすくなります。

やりたいこと使う句・考え方
部署の種類を一度ずつ表示SELECT DISTINCT 部署
部署ごとの売上合計を表示GROUP BY 部署+SUM
集計前に対象の行を絞るWHERE
集計後に合計値などで絞るHAVING

3.集計結果をビューとして使う

ビューは、SELECTの結果を表のように参照するための仕組みです。年齢層ごとの顧客数を求める元の記事の例を見てみましょう。DISTINCTやGROUP BYを含むSELECTも、ビューの定義に使えます。

CREATE VIEW AgeGroupCounts AS
SELECT AgeGroup, COUNT(*) AS CustomerCount
FROM (
SELECT
CASE
WHEN Age BETWEEN 20 AND 29 THEN '20-29'
WHEN Age BETWEEN 30 AND 39 THEN '30-39'
WHEN Age BETWEEN 40 AND 49 THEN '40-49'
ELSE 'Other'
END AS AgeGroup
FROM Customers
) AS SubQuery
GROUP BY AgeGroup;
SELECT * FROM AgeGroupCounts;

CASEで年齢層を決め、GROUP BYで年齢層ごとにまとめ、COUNT(*)で件数を数えています。ビューを使うと同じSELECTを繰り返し書かずに参照できます。セキュリティ面の効果は、権限やビューの設計にも依存します。

理解を確かめる確認問題

部署ごとの売上合計を出したいとき、DISTINCT 部署だけで求められるでしょうか。

解答・解説を見る

求められません。DISTINCTは結果の重複を除きます。部署ごとの合計には、GROUP BY 部署とSUM(売上)を組み合わせます。

まとめ:重複を除く目的と、集計する目的を分ける

一覧の重複を除くならDISTINCT、グループごとの計算ならGROUP BYと集約関数です。次に迷いやすいのは、集計条件をWHEREとHAVINGのどちらへ書くかです。

参考:PostgreSQL公式ドキュメント:SELECT・GROUP BY・HAVING・DISTINCT

コメント