目的
一つのテーブルに複数のグループがごちゃ混ぜに入っている場合に、グループごとに順位付けを行うSQLをメモる。
テストデータ
以下のようなデータを例にする。中学生のテスト結果のようなイメージ。
classがクラス、socreに点数、nameが氏名としたとき、クラス毎に順位を出したいとする。
class | score | name -------+-------+-------------- D | 58 | 大宮正春 E | 83 | 富永秀雄 C | 56 | 宮原里菜 A | 81 | 秋本早百合 A | 55 | 小澤栄作 B | 47 | 平本桃香 B | 80 | 前島千穂 C | 60 | 吉野美紀子 D | 68 | 岩本芳子 E | 96 | 大平裕美 A | 75 | 吉岡肇 E | 32 | 増井公一 E | 67 | 細井幸樹 D | 78 | 長谷部章太郎 B | 68 | 池本尚 C | 94 | 室井竹雄
順位付けするSQL
以下のSQLで順位付けができる。OVER句を使ってclass毎に並び替えたうえでROW_NUMBER()で順位を振ることができる。
SELECT * ,ROW_NUMBER() OVER (PARTITION BY class ORDER BY score DESC) AS ranking FROM results
結果
右端が順位です。
class | score | name | ranking -------+-------+--------------+-------- A | 81 | 秋本早百合 | 1 A | 75 | 吉岡肇 | 2 A | 55 | 小澤栄作 | 3 B | 80 | 前島千穂 | 1 B | 68 | 池本尚 | 2 B | 47 | 平本桃香 | 3 C | 94 | 室井竹雄 | 1 C | 60 | 吉野美紀子 | 2 C | 56 | 宮原里菜 | 3 D | 78 | 長谷部章太郎 | 1 D | 68 | 岩本芳子 | 2 D | 58 | 大宮正春 | 3 E | 96 | 大平裕美 | 1 E | 83 | 富永秀雄 | 2 E | 67 | 細井幸樹 | 3 E | 32 | 増井公一 | 4
特定の順位だけを抜き出すSQL
サブクエリを使用することで、各クラスの特定の順位の人だけを抜き出すこともできます。以下は各クラス1番の人だけを抜き出すコードです。
SELECT * FROM ( SELECT * ,ROW_NUMBER() OVER (PARTITION BY class ORDER BY score DESC) AS ranking FROM results ) as T WHERE seqnum = 1
結果
class | score | name | ranking -------+-------+--------------+-------- A | 81 | 秋本早百合 | 1 B | 80 | 前島千穂 | 1 C | 94 | 室井竹雄 | 1 D | 78 | 長谷部章太郎 | 1 E | 96 | 大平裕美 | 1
短いコードですが、結構使い勝手がいいです。