スマートスタイル TECH BLOG

データベース&クラウド技術情報

MySQL8.0のWindow関数を分かりやすく紹介する(2.順位・連番の付け方(基本編))

はじめに

MySQL8.0がリリースされたことにより、Window関数の利用が可能になりました。
Oracle、PostgreSQL、SQL Server等でも利用できる関数ですが、「難しそう」、「どういう場合に使えば良いかわからない」というイメージを持たれている方もいると思いますので、この記事ではシンプルにどのようなことが出来るのかを紹介していきます。

過去の記事でもWindow関数について分かりやすく記載しておりますので、確認されていない方は是非こちらの記事もご参照ください。
MySQL8.0のWindow関数を分かりやすく紹介する(1.「集計関数×Window関数」のコラボ)

今回は第二弾として「順位・連番の付け方(基本編)」というお題で記載します。
Window関数の中でも利用頻度が高い関数を3つほど利用し、基本的な使い方、考え方を紹介していきますので、この機会に是非覚えていただけると幸いです。

データ準備

以下のように、好きな食べ物の情報と投票数(votes)を管理する検証用テーブルを作成します。
もし「好きな食べ物が見当たらない!」、「この投票数はちょっと納得できない!!」と思われた方は、お手元の環境で自由にデータを登録頂いた後に、後ほど紹介する方法を実施して結果の出力ができるとスッキリすると思います。是非テストデータの作成から拘って試してみてください。

「順位を付けたい!」でもSQL文はどう記述するの?

例えば「投票数」に対して順位付けしたい時、どのようにSQL文を記述すべきでしょうか?
実はWindow関数を利用する/しない場合、どちらのケースでも記述することができます。また順位付けの考え方(Window関数の種類)は大きく分けて2つありますので、ケース毎に紹介します。

ケース1:RANK関数で順位付け

1つ目のケースとして(1位、2位、2位、4位・・・)のように、
同順位に対して同じ番号をつけ、次の順位(3位)はスキップしたい場合です。

この場合は以下のようにWindow関数のRANK関数が利用できます。
ポイントとしてはOVER句の後ろにORDER BY votes DESCと指定している点です。このORDER BY句を記述することによって、votesの降順で並び替えた「順位」が表示できます。

もしRANK関数を利用しない場合は、以下のようにSELECT句にサブクエリを記述するような方法があります。MySQL8.0より前のバージョンでは「ずっと試行錯誤していた・・・」という方もいると思いますので、この機会にRANK関数を利用してみてください。

ケース2:DENSE_RANK関数で順位付け

2つ目のケースとして(1位、2位、2位、3位・・・)のように、
同順位に対して同じ番号をつけ、次の順位(3位)はスキップしない場合です。

以下のようにWindow関数のDENSE_RANK関数が利用でき、ORDER BY votes DESCと指定している点、考え方はケース1のRANK関数と全く同じです。

次にDENSE_RANK関数を利用しない場合は、やはり以下のようにSELECT句にサブクエリを記述して頑張っていくような方法があります。distinctを使用することで、votesの重複データを除外した上で、件数をカウントしていることがポイントになります。

ベスト、ワーストランキングの作成

ここでは「投票数」に対してのベスト、ワーストランキングを作成します。
「ベスト」、「ワースト」の切り替えはORDER BY句の並び順を指定することで制御できます。

以下ではORDER BY votes DESCORDER BY votes ASCとすることで、DESC(降順)、ASC(昇順)で並び替えをしていることがわかります。

また前回の記事(MySQL8.0のWindow関数を分かりやすく紹介する(1.「集計関数×Window関数」のコラボ))で紹介した「名前付きWindow」を利用することで、より簡潔なSQL文になっていると思います。

「連番を付けたい」→「迷わずROW_NUMBER関数を使おう!」

まず「順位」と「連番」の違いについて、簡単に整理すると以下のようになります。

用語 説明
順位 同順位に対して同じ番号を割り振ります。 (例.1位、2位、2位、4位・・・)
連番 他の行と重複しない一意な番号を割り振ります。(例.1、2、3、4・・・)

例えば「投票数」に対して、「ROW_NUMBER」、「RANK」、「DENSE_RANK」関数を利用した場合、以下のようにROW_NUMBER関数の結果(serial_number)だけ、きちんと「連番」になっていることがわかります。
「連番」=「ROW_NUMBER関数」という意識を1つだけ持っていただけると間違いはないですね。

まとめ

今回はWindow関数を利用して、順位・連番の付け方の基本を紹介しました。
Window関数を利用することでSQL文が簡潔になり、ソース(SQL文)のメンテナンス性も高くなると思いますので、是非興味を持って利用していただけると幸いです。

Return Top