MySQL
 Computer >> コンピューター >  >> プログラミング >> MySQL

MySQLのDISTINCTとGROUP BYの違いとは?使い分け方を実例付きで解説

DISTINCTとGROUP BY、どちらを使うべき?

MySQLで重複データを処理する場合、「SELECT DISTINCT」と「GROUP BY」のどちらを使えばよいか迷うことがあります。この記事では、それぞれの特徴と使い分けのポイントを、実際のSQL実行例を交えてわかりやすく解説します。

SELECT DISTINCTで重複する値を除外する

SELECT DISTINCTは、指定したカラムの一意な値(重複しない値)を取得するために使います。重複レコードを取り除く目的で利用されるほか、MAXAVGといった集計関数と組み合わせることも可能です。単一のカラムに対して適用できるのが特徴です。

サンプルテーブルの作成

まず、CREATE文を使ってテーブルを作成します。

mysql> CREATE TABLE DistinctDemo
    -> (
    -> id int,
    -> name varchar(100)
    -> );
Query OK, 0 rows affected (0.64 sec)

レコードの挿入

続いて、INSERT文でテストデータを挿入します。

mysql> INSERT into DistinctDemo values(1,'John');
Query OK, 1 row affected (0.17 sec)

mysql> INSERT into DistinctDemo values(2,'John');
Query OK, 1 row affected (0.18 sec)

mysql> INSERT into DistinctDemo values(3,'Bob');
Query OK, 1 row affected (0.17 sec)

mysql> INSERT into DistinctDemo values(4,'John');
Query OK, 1 row affected (0.15 sec)

mysql> INSERT into DistinctDemo values(5,'David');
Query OK, 1 row affected (0.17 sec)

mysql> INSERT into DistinctDemo values(6,'Bob');
Query OK, 1 row affected (0.16 sec)

全レコードの確認

SELECT文ですべてのレコードを表示してみましょう。

mysql> SELECT * from DistinctDemo;

上記クエリを実行すると、次のような結果が得られます。

+------+-------+
| id   | name  |
+------+-------+
| 1    | John  |
| 2    | John  |
| 3    | Bob   |
| 4    | John  |
| 5    | David |
| 6    | Bob   |
+------+-------+
6 rows in set (0.00 sec)

ご覧のとおり6件のレコードがあり、そのうち「John」と「Bob」が重複しています。ここでDISTINCTを使えば、重複レコードを取り除くことができます。構文は以下のとおりです。

SELECT DISTINCT column_name FROM yourTableName ORDER BY column_name;

DISTINCTで重複を削除する

実際に上記の構文を適用して、重複を除去してみます。

mysql> SELECT DISTINCT name from DistinctDemo;

実行結果は次のとおりです。

+-------+
| name  |
+-------+
| John  |
| Bob   |
| David |
+-------+
3 rows in set (0.00 sec)

重複が排除され、「John」「Bob」「David」の3件だけが取得できました。

GROUP BYでデータをグループ化して集計する

GROUP BYは、複数のカラムから取得したデータを、指定した1つ以上のカラムの値ごとにグループ化するために使います。こちらも集計関数(SUM、AVGなど)と組み合わせて利用できます。

サンプルテーブルの作成

まず、CREATE文でテーブルを作成します。

mysql> CREATE table GroupDemo1
    -> (
    -> id int,
    -> name varchar(100),
    -> address varchar(100)
    -> );
Query OK, 0 rows affected (0.68 sec)

レコードの挿入

テーブル作成後、次のようにレコードを挿入します。

mysql> INSERT into GroupDemo1 values(1,'John','US');
Query OK, 1 row affected (0.18 sec)

mysql> INSERT into GroupDemo1 values(2,'Bob','UK');
Query OK, 1 row affected (0.13 sec)

mysql> INSERT into GroupDemo1 values(3,'David','US');
Query OK, 1 row affected (0.12 sec)

mysql> INSERT into GroupDemo1 values(4,'David','US');
Query OK, 1 row affected (0.15 sec)

全レコードの確認

SELECT文で登録済みのレコードをすべて表示します。

mysql> SELECT * from GroupDemo1;

実行結果は以下のとおりです。

+------+-------+---------+
| id   | name  | address |
+------+-------+---------+
| 1    | John  | US      |
| 2    | Bob   | UK      |
| 3    | David | US      |
| 4    | David | US      |
+------+-------+---------+
4 rows in set (0.00 sec)

GROUP BYで出現回数を集計する

ここでGROUP BYを使って、同じ住所(address)がそれぞれ何回出現するかを集計してみましょう。構文は以下のとおりです。

SELECT column_name1, ......N aggregate_function() FROM yourTableName GROUP BY column_name;

実際にこの構文を適用してみます。

mysql> SELECT address, count(*) from GroupDemo1 group by address;

実行結果は次のとおりです。

+---------+----------+
| address | count(*) |
+---------+----------+
| US      | 3        |
| UK      | 1        |
+---------+----------+
2 rows in set (0.00 sec)

まとめ:DISTINCTとGROUP BYの使い分け

DISTINCTは、重複を排除して一意な値のリストを取得したい場合に最適です。
GROUP BYは、グループごとの件数や合計など、集計を行いたい場合に適しています。

単純に重複をなくすだけならDISTINCT、グループごとの統計情報が必要ならGROUP BYというように、目的に応じて使い分けるのがポイントです。

  1. MySQLでテーブルの重複を除いたレコードから平均値を取得するクエリの書き方

    MySQLで平均値を求めるには AVG() 関数を使用します。さらに DISTINCT と組み合わせることで、重複しているレコードを除外した状態で平均を計算することができます。この記事では、実際にサンプルテーブルを作成しながら、個別(ユニーク)なレコードから平均値を取得する方法を解説します。サンプルテーブルの作成まず、以下のクエリでテーブルを作成します。mysql> create table DemoTable1934 ( StudentName varchar(20), StudentMarks int ); Query OK, 0 rows affec

  2. MySQLで最高額の給与を取得する方法

    ```html MySQLで最高額の給与を取得するには? テーブルの中から最も高い給与(最高額の給料)を取得したい場合は、集計関数の MAX() を使用します。MAX() 関数は、指定したカラムの中で最大の値を返してくれる便利な関数です。 基本構文 select MAX(yourColumnName) AS anyAliasName from yourTableName; サンプルテーブルの作成 まず、実際に動作を確認するためのテーブルを作成しましょう。 mysql> create table demo44 -> ( -> employee_id int not null