DISTINCTは「同じ値の組合せを一度だけ表示したい」とき、GROUP BYは「同じ値の行をまとめたい」ときに使います。似た結果になることもありますが、まず目的から区別しましょう。
この記事で違いとビューでの使い方を確認し、集計条件の使い分けは末尾の無料noteで例題に進めます。
1.一覧を重複なく出すならDISTINCT
SELECTで指定した列の値の組合せが同じ行を、結果から重複なく表示します。元の表の行を削除する命令ではありません。
SELECT DISTINCT 部署
FROM 売上表;
営業の行が複数あっても、部署の一覧には営業を一度だけ表示します。複数列を指定した場合は、その組合せで重複を判断します。
2.部署ごとの合計を出すならGROUP BY

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のどちらへ書くかです。

コメント