PostgreSQLで順位付け!ROW_NUMBER関数の使い方を初心者向けに徹底解説
生徒
「テストの結果や売上のデータに、上から順番に番号を振りたいときはどうすればいいんですか?」
先生
「そんなときはPostgreSQLの『ROW_NUMBER(ロウ・ナンバー)』という機能を使うのが一番です。列に1番、2番と自動で番号をつけてくれるんですよ。」
生徒
「それって、エクセルで1、2と入力して下に引っ張るような感じですか?」
先生
「まさにその通りです!データベースにある大量のデータに対しても、一瞬で正確な順位をつけることができます。プログラミングが初めてでも、書き方さえ覚えれば魔法のように動かせますよ。」
1. データベースの「順位付け」とは?
データベースとは、コンピュータの中に作られた「整理整頓された情報の保管庫」のことです。その中でも、特に人気のあるシステムが「PostgreSQL(ポストグレスキューエル)」です。
私たちが日常生活で「名簿を背の順に並べる」とか「テストの点数が高い順に並べる」といった作業をするように、データベースでもデータを特定のルールで並べ替え、そこに「1番目、2番目……」と番号を振りたい場面がよくあります。これを「順位付け」や「ナンバリング」と呼びます。
通常、データは保存された順番でバラバラに入っていますが、SQL(エスキューエル)というデータベースに命令を出す言葉を使えば、自由自在に順番を整理して番号をつけることができるのです。
2. ROW_NUMBER関数の基本を学ぼう
「ROW_NUMBER(ロウ・ナンバー)」は、直訳すると「行の番号」という意味です。これは「ウィンドウ関数」という少し高度な機能の一つですが、初心者の方でも使い方はシンプルなので安心してください。
この機能を使うと、指定した順番に従って、それぞれの行に「1」から始まる連番を割り振ることができます。例えば、100人の顧客データがあったとして、名前のあいうえお順に1番から100番まで番号を振る、といったことが簡単にできます。
まず、基本となるテーブル(データの表)を見てみましょう。今回は「テストの結果」を管理する「exam_scores」という表を例にします。
id | student_name | score | subject
---+--------------+-------+----------
1 | 佐藤太郎 | 85 | 数学
2 | 鈴木花子 | 92 | 数学
3 | 高橋健太 | 78 | 数学
4 | 田中愛子 | 95 | 数学
5 | 伊藤洋介 | 88 | 数学
6 | 渡辺真美 | 82 | 数学
この表から、点数が高い順に順位をつけてみましょう。以下のSQLコードを使います。
SELECT
student_name,
score,
ROW_NUMBER() OVER(ORDER BY score DESC) as rank
FROM exam_scores;
ここで出てきた「OVER(ORDER BY score DESC)」という部分は、「スコア(score)が大きい順(DESC)に並べて、その上で番号を振ってください」という命令です。実行結果は以下のようになります。
student_name | score | rank
-------------+-------+------
田中愛子 | 95 | 1
鈴木花子 | 92 | 2
伊藤洋介 | 88 | 3
佐藤太郎 | 85 | 4
渡辺真美 | 82 | 5
高橋健太 | 78 | 6
いかがでしょうか?「rank」という新しい列が作られ、点数が高い順に1番から6番まで綺麗に番号が振られましたね。
3. グループごとに順位をつける(PARTITION BY)
次に、もう少し複雑なことをしてみましょう。例えば「クラスごと」や「教科ごと」といったグループに分けて、そのグループ内だけで1番から番号を振りたい場合があります。これを実現するのが「PARTITION BY(パーティション・バイ)」というキーワードです。
「パーティション」とは「仕切り」のことです。大きな部屋をパーテーションで区切るように、データをグループごとに区切ってから、その中で順番を決めます。
新しいデータを見てみましょう。今度は「数学」と「英語」の点数が混ざった表です。
id | student_name | subject | score
---+--------------+---------+-------
1 | 佐藤太郎 | 数学 | 85
2 | 佐藤太郎 | 英語 | 70
3 | 鈴木花子 | 数学 | 92
4 | 鈴木花子 | 英語 | 88
5 | 田中愛子 | 数学 | 95
6 | 田中愛子 | 英語 | 98
この表を使って、「教科ごとに」点数が高い順に番号を振ってみます。
SELECT
subject,
student_name,
score,
ROW_NUMBER() OVER(PARTITION BY subject ORDER BY score DESC) as rank_in_subject
FROM exam_scores;
「PARTITION BY subject」と書くことで、まず教科でグループ分けし、そのグループの中で「ORDER BY score DESC(点数が高い順)」に並べています。結果は次の通りです。
subject | student_name | score | rank_in_subject
--------+--------------+-------+-----------------
数学 | 田中愛子 | 95 | 1
数学 | 鈴木花子 | 92 | 2
数学 | 佐藤太郎 | 85 | 3
英語 | 田中愛子 | 98 | 1
英語 | 鈴木花子 | 88 | 2
英語 | 佐藤太郎 | 70 | 3
数学の中での1位から3位、英語の中での1位から3位というように、別々に番号がつきました。このようにグループ分けして集計するのは、ビジネスの現場でも非常によく使われるテクニックです。
4. 応用編:重複がある場合の注意点
「ROW_NUMBER」を使うときに知っておくべき大切なルールがあります。それは、もし「同じ点数の人がいた場合でも、必ず違う番号を振る」ということです。
例えば、90点の人が二人いたとしても、ROW_NUMBERは一方に「1」、もう一方に「2」と番号をつけます。これは「単純な行番号」としての役割を果たすためです。
もし「同じ点数なら同じ順位にしたい(例:両方1位にする)」という場合は、「RANK」や「DENSE_RANK」という別の関数を使いますが、まずは一番基本で使い勝手の良い「ROW_NUMBER」をマスターしましょう。
最後に、会員の登録順に番号を振る例を見てみましょう。これは顧客管理システムなどで「古い順にIDを割り振る」ときなどに役立ちます。
id | user_name | joined_date
---+-----------+------------
1 | 岡田 | 2023-01-10
2 | 斉藤 | 2023-02-15
3 | 山本 | 2023-01-05
4 | 井上 | 2023-03-01
入会した日付(joined_date)が古い順に、会員番号をつけてみます。
SELECT
user_name,
joined_date,
ROW_NUMBER() OVER(ORDER BY joined_date ASC) as member_seq
FROM users;
「ASC」は「昇順(小さい順、古い順)」という意味です。
user_name | joined_date | member_seq
----------+-------------+------------
山本 | 2023-01-05 | 1
岡田 | 2023-01-10 | 2
斉藤 | 2023-02-15 | 3
井上 | 2023-03-01 | 4
日付順に正しく番号が振られましたね。
5. SQL用語集:今回出てきた難しい言葉
今回学習した内容の中で、少し難しく感じたかもしれない用語を整理しておきます。これらを覚えると、エンジニアの人たちとも会話ができるようになりますよ。
- クエリ (Query):データベースに対する「命令文」のことです。今回書いたSELECT文などがこれにあたります。
- レコード (Record):データベースの表における「1行分」のデータのことです。
- カラム (Column):データベースの表における「列(縦の項目)」のことです。「名前」や「点数」がカラムです。
- 昇順・降順 (ASC・DESC):数字や日付を並べる向きのことです。小さい順(古い順)が昇順、大きい順(新しい順)が降順です。
- 関数 (Function):特定の処理を自動で行ってくれる仕組みのことです。「ROW_NUMBER」も関数の一つです。
いかがでしたか?PostgreSQLの「ROW_NUMBER」を使えば、手作業では時間がかかる順位付けも、一瞬で、しかも正確に終わらせることができます。
最初は「OVER」や「ORDER BY」といった英単語が並んでいて難しく感じるかもしれませんが、自分で何度も書いて実行してみることで、自然と体が覚えていきます。まずは身近なデータ(自分の好きな食べ物リストなど)を想像して、それをどうやって並べ替えたいか考えるところから始めてみてください。
データベースの世界には、まだまだ便利な機能がたくさんあります。一つずつ階段を登るように学んでいけば、あなたも立派なデータの扱い手になれるはずです。