SQL の DISTINCT を使うサンプル

## 概要

- SQL の DISTINCT を使うサンプルを書く
- 環境: MySQL Ver 8.0.21 for osx10.15 on x86_64 (Homebrew) 

## DISTINCT とは

指定したカラムにおいて重複するデータを取り除いて出力することができる機能。

[SELECT \(SQL\) \- Wikipedia](https://ja.wikipedia.org/wiki/SELECT_(SQL))

> DISTINCT(UNIQUE)...テーブルに同じデータ行がある場合、重複を取り除いた1件のみを返す。

[MySQL :: MySQL 5\.6 リファレンスマニュアル :: 13\.2\.9 SELECT 構文](https://dev.mysql.com/doc/refman/5.6/ja/select.html)

> ALL および DISTINCT オプションは、重複した行を返すかどうかを指定します。ALL (デフォルト) は、重複を含め、一致するすべての行を返すように指定します。DISTINCT は、重複した行の結果セットからの削除を指定します。両方のオプションを指定するとエラーになります。

## サンプルデータを準備

買ったお菓子テーブルを作成。

```
mysql> CREATE TABLE katta_okashi (
    ->   number INTEGER,
    ->   name   VARCHAR(128),
    ->   okashi VARCHAR(128),
    ->   price  INTEGER
    -> );
Query OK, 0 rows affected (0.02 sec)
```

買ったお菓子データを追加。

```
mysql> INSERT INTO katta_okashi VALUES
    ->   (1, 'Alice', 'candy',     100),
    ->   (2, 'Alice', 'candy',      50),
    ->   (3, 'Alice', 'cookie',     30),
    ->   (4, 'Bob',   'chocolate', 200),
    ->   (5, 'Bob',   'chocolate',  20),
    ->   (6, 'Bob',   'cookie',     20);
Query OK, 6 rows affected (0.03 sec)
Records: 6  Duplicates: 0  Warnings: 0
```

買ったお菓子データ一覧を出力。

```
mysql> select * from katta_okashi;
+--------+-------+-----------+-------+
| number | name  | okashi    | price |
+--------+-------+-----------+-------+
|      1 | Alice | candy     |   100 |
|      2 | Alice | candy     |    50 |
|      3 | Alice | cookie    |    30 |
|      4 | Bob   | chocolate |   200 |
|      5 | Bob   | chocolate |    20 |
|      6 | Bob   | cookie    |    20 |
+--------+-------+-----------+-------+
6 rows in set (0.00 sec)
```

## カラムを指定して重複行をまとめる

カラムにて一意となるデータになるように重複したデータを取り除いて出力できる。

name には何パターンのデータが入っているか。

```
mysql> select distinct name from katta_okashi;
+-------+
| name  |
+-------+
| Alice |
| Bob   |
+-------+
2 rows in set (0.01 sec)
```

okashi には何パターンのデータが入っているか。

```
mysql> select distinct okashi from katta_okashi;
+-----------+
| okashi    |
+-----------+
| candy     |
| cookie    |
| chocolate |
+-----------+
3 rows in set (0.00 sec)
```

## 複数カラムを指定して重複行をまとめる

複数カラムで一意となるデータ (組み合わせパターン分) が出力される。

```
mysql> select distinct name, okashi from katta_okashi;
+-------+-----------+
| name  | okashi    |
+-------+-----------+
| Alice | candy     |
| Alice | cookie    |
| Bob   | chocolate |
| Bob   | cookie    |
+-------+-----------+
4 rows in set (0.00 sec)
```

## カラム内の一意なデータのカウント

name が何種類あるか。

```
mysql> select count(distinct name) from katta_okashi;
+----------------------+
| count(distinct name) |
+----------------------+
|                    2 |
+----------------------+
1 row in set (0.00 sec)
```

okashi が何種類あるか。

```
mysql> select count(distinct okashi) from katta_okashi;
+------------------------+
| count(distinct okashi) |
+------------------------+
|                      3 |
+------------------------+
1 row in set (0.01 sec)
```

複数カラム name と count の組み合わせが何パターンあるか。

```
mysql> select count(distinct name, okashi) from katta_okashi;
+------------------------------+
| count(distinct name, okashi) |
+------------------------------+
|                            4 |
+------------------------------+
1 row in set (0.02 sec)
```

## ORDER BY と組み合わせる

カラム内で一意となるデータを並び替えてから出力できる。

```
mysql> select distinct name from katta_okashi order by name desc;
+-------+
| name  |
+-------+
| Bob   |
| Alice |
+-------+
2 rows in set (0.01 sec)
```

## 参考資料

- [MySQL :: MySQL 5\.6 リファレンスマニュアル :: 13\.2\.9 SELECT 構文](https://dev.mysql.com/doc/refman/5.6/ja/select.html)
- [【SQL入門】DISTINCTで重複行をまとめる方法をわかりやすく解説 \| 侍エンジニア塾ブログ（Samurai Blog） \- プログラミング入門者向けサイト](https://www.sejuku.net/blog/54990)
- [SQL: DISTINCT と GROUP BY って，何がちがうの？ \- Qiita](https://qiita.com/masniimura/items/7ac62b37f6b42c4e17bc)