【PostgreSQL】グループ内での順位付けを行うSQL
目的
一つのテーブルに複数のグループがごちゃ混ぜに入っている場合に、グループごとに順位付けを行うSQLをメモる。
テストデータ
以下のようなデータを例にする。中学生のテスト結果のようなイメージ。
classがクラス、socreに点数、nameが氏名としたとき、クラス毎に順位を出したいとする。
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 | 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()で順位を振ることができる。
01 02 03 04 | SELECT * ,ROW_NUMBER() OVER (PARTITION BY class ORDER BY score DESC ) AS ranking FROM results |
結果
右端が順位です。
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 | 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番の人だけを抜き出すコードです。
01 02 03 04 05 06 07 08 09 10 | SELECT * FROM ( SELECT * ,ROW_NUMBER() OVER (PARTITION BY class ORDER BY score DESC ) AS ranking FROM results ) as T WHERE seqnum = 1 |
結果
01 02 03 04 05 06 07 | class | score | name | ranking -------+-------+--------------+-------- A | 81 | 秋本早百合 | 1 B | 80 | 前島千穂 | 1 C | 94 | 室井竹雄 | 1 D | 78 | 長谷部章太郎 | 1 E | 96 | 大平裕美 | 1 |
短いコードですが、結構使い勝手がいいです。