CodeGym /コース /SQL SELF /DISTINCTでユニークな値を抽出する

DISTINCTでユニークな値を抽出する

SQL SELF
レベル 6, レッスン 1
使用可能

たまにデータベースって、記憶力が悪い人みたいな感じしない?全部メモるけど、すでに書いたことを忘れちゃう。で、クライアントの都市のテーブルを開くと、「ベルリン」が10個、「シアトル」が5個、他にも同じのがいっぱい。これは、同じ都市が違うクライアントで何回も出てくるからなんだよね。でも、広告キャンペーンを「ベルリン」10個分で作りたいわけじゃなくて、1都市分だけでいいでしょ?

ユニークな値だけを取り出したい時――重複なしで――便利なのが DISTINCT コマンド。まるで魔法のモップみたいに、一振りで重複行を消して、本当に違うものだけ残してくれる。

DISTINCT を使うと、クエリの結果からユニークな行だけを抽出できる。これは、例えばこんな重複データを消したい時に便利:

  • 注文内のユニークな商品。
  • ユニークなクライアント名。
  • 「都市+国」みたいなユニークなデータの組み合わせ。

DISTINCT はどう動く?

DISTINCT のシンタックスは超シンプルで分かりやすい。SQLってだいたいそうだよね:

SELECT DISTINCT カラム1, カラム2, ...
FROM テーブル;

クエリに DISTINCT を追加すると、データベースは結果の各行がユニークになるようにしてくれる。

DISTINCT の使い方例

まずはクラシックな例から、DISTINCT がどう動くか見てみよう。

例1:1つのカラムのユニークな値

例えば、students という学生データのテーブルがあるとする:

-- テーブル students

id first_name last_name city
1 Maria Chi Seattle
2 Alex Lin Toronto
3 Anna Song Seattle
4 Nat Cole Chicago
5 Maria Chi Seattle

学生たちがどの都市から来てるか知りたいとき、こう書く:

SELECT city
FROM students;

で、結果はこう:

city
Seattle
Toronto
Seattle
Chicago
Seattle

ちょっと思ってたのと違う :(

重複を消したいなら DISTINCT を使う:

SELECT DISTINCT city
FROM students;

結果:

city
Seattle
Toronto
Chicago

DISTINCT なしだと「Seattle」が3回出てくるけど、欲しいのは1回だけだよね。

例2:複数カラムのユニークな値

今度は、「名前+苗字」のユニークな組み合わせを取得したいとする。学生の中には同じ苗字や名前の人もいるかもしれないし。

同じく students テーブルを使う:

-- テーブル students

id first_name last_name city
1 Maria Chi Seattle
2 Alex Lin Toronto
3 Anna Song Seattle
4 Nat Cole Chicago
5 Maria Chi Seattle

クエリ:

SELECT DISTINCT first_name, last_name
FROM students;

結果:

first_name last_name
Maria Chi
Alex Lin
Anna Song
Nat Cole

こんな感じで、DISTINCT はフィルターみたいに動く。指定したカラム全部を見て、全部の値が同じ行だけ重複として消してくれる。

例3:ユニークな組み合わせ+ソート

今度は DISTINCT と ORDER BY を組み合わせて、ユニークな値を苗字のアルファベット順で並べてみよう。

またまた students テーブル:

-- テーブル students

id first_name last_name city
1 Maria Chi Seattle
2 Alex Lin Toronto
3 Anna Song Seattle
4 Nat Cole Chicago
5 Maria Chi Seattle

クエリ:

SELECT DISTINCT first_name, last_name
FROM students
ORDER BY last_name ASC;

結果:

first_name last_name
Maria Chi
Nat Cole
Alex Lin
Anna Song

重複行は消えて、苗字はアルファベット順に並んでる。

例4:集計関数で使う

じゃあ、DISTINCT を COUNT みたいな関数で使ったらどうなる?

SELECT COUNT(DISTINCT city) AS unique_city_count
FROM students;

結果:

unique_city_count
3

このクエリはユニークな都市の数を返してくれる。便利だよね?

DISTINCT の動作の特徴

DISTINCT を使うときは、指定したカラム全部でユニークかどうかが決まるってことを理解しておこう。クエリにカラムを増やすと、結果も変わるかも。

例5:なぜコンテキスト理解が大事?

クエリに追加のフィールドを入れると、行のユニークさに影響することがある。

SELECT DISTINCT first_name, city
FROM students;

students テーブル:

id first_name last_name city
1 Maria Chi Seattle
2 Alex Lin Austin
3 Anna Song Seattle
4 Otto Art Denver
5 Maria Chi Portland

結果:

first_name city
Maria Seattle
Alex Austin
Anna Seattle
Otto Denver
Maria Portland

「名前+都市」の組み合わせが全部ユニークになってる。だから覚えておこう:ユニークさは指定した全カラムで決まる、1つ1つのカラムじゃないよ。

DISTINCT でよくあるミス

DISTINCT を使うときの一番ありがちなミスは、クエリが何をしてるかちゃんと理解してないこと。例えば、カラムを多く指定しすぎると、思ってたのと全然違う結果になることがある。なぜなら、全部のカラムでユニークかどうかが決まるから。

例えば:

SELECT DISTINCT *
FROM students;

この場合、全カラムが考慮されるから、各行が全部ユニーク扱いになる。

もう一つのミスは、DISTINCT がいらない場面で使っちゃうこと。例えば、すでにユニークなデータ(主キーのカラムとか)なら、DISTINCT はDBに余計な負荷をかけるだけ。

2
タスク
SQL SELF, レベル 6, レッスン 1
ロック未解除
顧客のユニークな都市
顧客のユニークな都市
2
タスク
SQL SELF, レベル 6, レッスン 1
ロック未解除
名前と苗字のユニークな組み合わせ
名前と苗字のユニークな組み合わせ
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION