こんにちは、Kinocodeです。
皆さんは値の重複を排除してカラムを抽出したい時、どのようにしていますか?
以前の動画で解説したGROUP BY句を思いつく方が多いかもしれません。
このGROUP BY句と同じような機能を持つものとして、distinctがあります。
SELECT句でカラムの前にdistinctと書くだけで、値の重複を排除してそのカラムを抽出することができます。
とても便利ですので、GROUP BY句だけでなくdistinctも是非使えるようにしましょう。
プログラミング学習サービス「キノクエスト」のご紹介
キノコードでは、プログラミングを習得するためのプログラミング学習サービス「キノクエスト」を運営しています。
Pythonの問題の他に、SQLの問題も120問以上あります。
キノクエストには、学習カリキュラムがあり、学習順番に悩むことなく学習を進められます。
月額1,990円と本1冊分の値段です。
キノクエストの特徴は下記の通りです。
- SQLの問題も120問以上
- プログラミング学習をしている仲間が集まるコミュニティがある
- 1000問以上の問題を解いてプログラミングを習得
- 環境構築不要ですぐに始められる
- 動画と連動しているので、インプットもできる。
- 月額1,990円で、コミュニティもセット
キノクエストを詳しく知りたい方は、紹介ページをご覧ください。
▼キノクエストの紹介ページはこちら▼
https://kino-code.com/kq_service_a/
それでは、レッスンスタートです。
distinctとは
distinctは値の重複を排除してカラムを抽出したいときに使います。
SELECT文では抽出するカラムの直前にdistinctを記述します。
distinctを追加したSELECT文の構文を確認しておきましょう。
SELECT distinct カラム1, カラム2... FROM テーブル
このようにしてdistinctを使って抽出したカラムには、一意の値だけが残ります。
そのためどのような値がカラムに存在しているか、一目瞭然で把握することができます。
distinctを使ったカラムの抽出
それではテーブルを作成して、distinctの使い方を具体的に見ていきましょう。
今回はproductsテーブルを使用します。
productsテーブルはid、category、item、priceの4つのカラムを持ったテーブルです。
まずdistinctを用いて、productsテーブルからcategoryのカラムを値の重複なしで抽出してみましょう。
SQLはこのように書くことができます。
抽出するcategoryのカラムの直前にdistinctと書けばOKです。
簡単ですね。
それでは実行します。
SELECT distinct category FROM products;
もともとproductsテーブルのcategoryには、outer、tops、shoesがそれぞれ2レコードずつ重複して存在していました。
distinctを使って抽出することで、これらの値の重複を排除して抽出することができました。
distinctを使った複数カラムの抽出
次にdistictを使って、複数のカラムをまとめて抽出してみましょう。
複数のカラムをまとめて抽出するときは、そのカラムに含まれる値の組み合わせの重複が排除されます。
言葉だけの説明だとわかりづらいと思いますので、さっそくSQLを書いて具体的に見ていきましょう。
ここではdistinctを使ってcategoryとitemのカラムをまとめて抽出してみます。
SQLはこのように書くことができます。
distinctは抽出する複数のカラムの先頭に書くようにしましょう。
それでは実行します。
SELECT distinct category, item FROM products;
抽出に使ったproductsテーブルを再度見てみましょう。
categoryとitemのカラムの値の組み合わせに注目してください。
そうするとshoesとsneakerの組み合わせに重複が見つかるはずです。
SQLの実行結果ではこのshoesとsneakerの値の組み合わせの重複が排除されています。
このようにdistinctを使って複数カラムをまとめて抽出すると、一意の値の組み合わせを表示することができます。
distinctをcountと併用する
今度はdistinctをcount関数と併用して使ってみましょう。
distictを使って抽出したカラムには一意の値だけが残ります。
このことは、ここまでの説明からご理解いただけているかと思います。
この一意の値は、カラムに存在する値の種類を表します。
これをカウントすることで、カラムに何種類の値が存在するかを調べることができます。
それでは、このようなSQLを書いて、categoryに何種類の値が存在するか調べてみましょう。
SELECT count(distinct category) FROM products;
categoryは重複を排除すると、outer, tops, shoesの3種類の値が存在しています。
これをcount関数で数えるので、実行結果には3が表示されます。
このようにdistinctとcount関数を併用することで、カラムに何種類の値が存在するかを簡単に調べることができます。
GROUP BY句との違い
最後にdistinctとGROUP BY句の違いを確認しておきましょう。
カラムを値の重複なしで抽出するために、distinctと別にGROUP BY句を使うこともできます。
distictよりGROUP BY句の方を、よく利用されている方も多いのではないでしょうか。
distinctを用いた抽出は、GROUP BY句で書き換え可能なケースがほとんどです。
しかしSQLの実行結果が同じでも、distinctとGROUP BY句では重複を排除する処理が異なります。
ここでは厳密な説明は行いませんが、「distinctは重複した値を排除」し、「GROUP BY句は重複した値を一つにまとめる」とイメージすると分かりやすいでしょう。
これを頭に入れた上で、最初に説明したSQLを見てみましょう。
このSQLではcategoryを値の重複なしで抽出しています。
SELECT distinct category FROM products;
このSQLはこのように、GROUP BY句で書き換えることができます。
SELECT category FROM products
GROUP BY category;
重複した値を除外しようが、一つにまとめようが、一意の値が抽出されることに変わりありません。
そのためカラムを値の重複なしで抽出するうえでは、distinctとGROUP BY句のどちらを使うこともできます。
一方でこのようなGROUP BY句を使った集計を、distinctで書き換えることはできません。
SELECT category, SUM(price) FROM products
GROUP BY category;
このSQLではGROUP BY句でcategoryのカラムを指定して、categoryのカラムの値ごとにpriceのカラムをSUM関数で集計しています。
distinctは特定のカラムをもとに集計するような処理には向いていません。
そのためこうした集計を行いたい時は、distinctではなく、GROUP BY句を使うようにしましょう。