Webサイト制作コースのお申し込みはこちら Webサイト制作コースのお申し込みはこちら

SQLのwhereでdistinctを使う方法についてまとめています。

SQLのwhereでdistinctとINを組み合わせる

distinctは重複データを除去するSQLです。where句でdistinctとIN、サブクエリを組み合わせて絞り込み条件に組み込むことが可能です。

以下は、雇用日(hire_date)が1985年2月1日以前の社員の、最新の年収(salary)を抽出する例です。

mysql> select employees.emp_no, first_name, last_name, salary
from employees left join salaries on employees.emp_no = salaries.emp_no
where salaries.to_date='9999-01-01'
and hire_date in ( select distinct hire_date from employees where hire_date < '1985-02-01');

+--------+-------------+--------------+--------+
| emp_no | first_name  | last_name    | salary |
+--------+-------------+--------------+--------+
| 110022 | Margareta   | Markovitch   | 108407 |
| 110085 | Ebru        | Alpin        |  88443 |
| 110114 | Isamu       | Legleitner   |  83457 |
| 110183 | Shirish     | Ossenbruggen |  79229 |
| 110303 | Krassimir   | Wegerle      |  72583 |
| 110511 | DeForest    | Hagimont     |  72903 |
| 110725 | Peternela   | Onuegbe      |  93193 |
| 111035 | Przemyslawa | Kaelbling    |  95873 |
| 111400 | Arie        | Staelin      | 103244 |
| 111692 | Tonny       | Butterworth  |  73953 |
+--------+-------------+--------------+--------+
10 rows in set (2.79 sec)

雇用日(hire_date)の重複を除去すると、1985-01-01と1985-01-14の2つのみになります。

mysql> select hire_date from employees where hire_date < '1985-02-01';
+------------+
| hire_date  |
+------------+
| 1985-01-01 |
| 1985-01-01 |
| 1985-01-14 |
| 1985-01-01 |
| 1985-01-01 |
| 1985-01-01 |
| 1985-01-01 |
| 1985-01-01 |
| 1985-01-01 |
| 1985-01-01 |
+------------+
10 rows in set (0.06 sec)

【関連記事】
SQL distinctとcountを組み合わせてデータ種類をカウントする

employeesのデータは約30万件あり、条件に指定しているhire_dateにはindexが設定されていないため、30万件のテーブルフルスキャンが発生しています。以下は、上記SQLをexplainにて表示した実行計画です。

type=ALL、key=NULLとなっている箇所が、indexを使わずテーブルフルスキャンが実行されている箇所です。

mysql> explain select employees.emp_no, first_name, last_name, salary from employees left join salaries on employees.emp_no = salaries.emp_no where salaries.to_date='9999-01-01' and hire_date in ( select distinct hire_date from employees where hire_date < '1985-02-01');
+----+--------------+-------------+------------+--------+---------------------+---------------------+---------+-------------------------------+--------+----------+-------------+
| id | select_type  | table       | partitions | type   | possible_keys       | key                 | key_len | ref                           | rows   | filtered | Extra       |
+----+--------------+-------------+------------+--------+---------------------+---------------------+---------+-------------------------------+--------+----------+-------------+
|  1 | SIMPLE       | employees   | NULL       | ALL    | PRIMARY             | NULL                | NULL    | NULL                          | 299433 |   100.00 | Using where |
|  1 | SIMPLE       | salaries    | NULL       | ref    | PRIMARY             | PRIMARY             | 4       | employees.employees.emp_no    |      9 |    10.00 | Using where |
|  1 | SIMPLE       | <subquery2> | NULL       | eq_ref | <auto_distinct_key> | <auto_distinct_key> | 3       | employees.employees.hire_date |      1 |   100.00 | NULL        |
|  2 | MATERIALIZED | employees   | NULL       | ALL    | NULL                | NULL                | NULL    | NULL                          | 299433 |    33.33 | Using where |
+----+--------------+-------------+------------+--------+---------------------+---------------------+---------+-------------------------------+--------+----------+-------------+
4 rows in set, 1 warning (0.00 sec)

重複を除去する方法として、distinctはgroup byと比較して処理が速いのです。しかし、where句で条件として使用すると、今回のように別の箇所でボトルネックが発生するケースもあります。

【関連記事】
SQL distinctのサンプルコード集 group byよりも700倍速い? 

まとめ

ポテパンダの一言メモ
  • distinctは重複するレコードを除去するSQL
  • distinctをwhere句で使うには、INとサブクエリを組み合わせる方法がある
  • distinct自体は処理が速いが、別の箇所でボトルネックが発生するケースあり

エンジニアになりたい人に選ばれるプログラミングスクール「ポテパンキャンプ 」

ポテパンキャンプは卒業生の多くがWebエンジニアとして活躍している実践型プログラミングスクールです。 1000名以上が受講しており、その多くが上場企業、ベンチャー企業のWebエンジニアとして活躍しています。

基礎的な学習だけで満足せず、実際にプログラミングを覚えて実践で使えるレベルまで学習したいという方に人気です。 プログラミングを学習し実践で使うには様々な要素が必要です。

それがマルっと詰まっているポテパンキャンプでプログラミングを学習してみませんか?

卒業生の多くがWebエンジニアとして活躍

卒業生の多くがWeb企業で活躍しております。
実践的なカリキュラムをこなしているからこそ現場でも戦力となっております。
活躍する卒業生のインタビューもございますので是非御覧ください。

経験豊富なエンジニア陣が直接指導

実践的なカリキュラムと経験豊富なエンジニアが直接指導にあたります。
有名企業のエンジニアも多数在籍し品質高いWebアプリケーションを作れるようサポートします。

満足度高くコスパの高いプログラミングスクール「ポテパンキャンプ」

運営する株式会社ポテパンは10,000人以上のエンジニアのキャリアサポートを行ってきております。
そのノウハウを活かして実践的なカリキュラムを随時アップデートしております。

代表の宮崎もプログラミングを覚えサイトを作りポテパンを創業しました。
本気でプログラミングを身につけたいという方にコスパ良く受講していただきたいと思っておりますので、気になる方はぜひスクール詳細をのぞいてくださいませ。