重複行をまとめるには GROUP BY と DISTINCT のどちらを使うべきか?
SQL: GROUP BY と DISTINCT の違い
DISTINCT:
DISTINCT は、SELECT 結果から重複行を 削除 する機能です。
- 例:
SELECT DISTINCT name
FROM users;
このクエリは、users
テーブルから重複する名前を除いて、すべての名前を 1行ずつ 表示します。
GROUP BY:
SELECT country, COUNT(*) AS count
FROM users
GROUP BY country;
このクエリは、users
テーブルを 国ごとにグループ化 し、各国のユーザー数 (COUNT(*)) を表示します。
重要な違い:
- DISTINCT は、重複行を削除 するだけですが、GROUP BY は グループ化 と 集計 を行います。
- DISTINCT は SELECT 句 で使用されますが、GROUP BY は GROUP BY 句 で使用されます。
- 重複行を 削除 したいだけの場合は DISTINCT を使用します。
- グループ化 と 集計 を行いたい場合は GROUP BY を使用します。
- 従業員の 部署と人数 を知りたい場合:
SELECT department, COUNT(*) AS count
FROM employees
GROUP BY department;
- 商品の カテゴリーと売上合計 を知りたい場合:
SELECT category, SUM(sales) AS total_sales
FROM products
GROUP BY category;
まとめ:
- DISTINCT と GROUP BY は、重複行を処理する SQL の機能ですが、異なる目的で使用されます。
テーブル構造:
CREATE TABLE employees (
id INT,
name VARCHAR(255),
department VARCHAR(255),
salary INT
);
INSERT INTO employees (id, name, department, salary) VALUES
(1, 'John Doe', 'Sales', 50000),
(2, 'Jane Doe', 'Marketing', 40000),
(3, 'John Smith', 'Sales', 50000),
(4, 'Jane Smith', 'Marketing', 40000),
(5, 'John Johnson', 'Sales', 50000);
1 部署と人数:
SELECT department, COUNT(*) AS count
FROM employees
GROUP BY department;
結果:
department | count
----------+-------
Sales | 3
Marketing | 2
2 部署と平均給与:
SELECT department, AVG(salary) AS average_salary
FROM employees
GROUP BY department;
department | average_salary
----------+--------------
Sales | 50000
Marketing | 40000
1 重複する名前:
SELECT DISTINCT name
FROM employees;
name
-----
John Doe
Jane Doe
John Smith
Jane Smith
John Johnson
SELECT DISTINCT department
FROM employees;
department
----------
Sales
Marketing
GROUP BY と DISTINCT の代替方法
- CASE 式:
SELECT CASE department
WHEN 'Sales' THEN '営業部'
WHEN 'Marketing' THEN 'マーケティング部'
ELSE department
END AS department, COUNT(*) AS count
FROM employees
GROUP BY department;
- SUBQUERY:
SELECT department, count
FROM (
SELECT department, COUNT(*) AS count
FROM employees
GROUP BY department
) AS t;
- UNIQUE キー:
CREATE UNIQUE INDEX idx_name ON employees (name);
SELECT name
FROM employees;
SELECT name
FROM (
SELECT DISTINCT name
FROM employees
) AS t;
その他の考慮事項:
- 処理速度: 代替方法の方が高速になる場合もあります。
- 読みやすさ: コードの読みやすさを考慮する必要があります。
- 機能制限: 使用するデータベースによっては、使用できない代替方法もあります。
sql group-by distinct