同額は同順位、次は飛ばす順位づけ
在籍中の社員に給与の高い順で順位を付けてください。給与が同額なら同じ順位とし、その次の順位は飛ばします(1, 2, 2, 4 のように付けます)。列は「順位, 名前, 給与」の順、順位の昇順に並べ、同順位のときは社員番号(shain_id)の小さい順にしてください。
主要 7 製品で通用 そのまま使える: PostgreSQL / MySQL / MariaDB / SQLite / SQL Server / Oracle Database / IBM Db2
- 同順位の次を飛ばすのが rank()、飛ばさず詰めるのが dense_rank()、同額でも別々の番号を振るのが row_number() です。
- ウィンドウ関数が使えるのは SQLite 3.25 以降・MySQL 8.0 以降です。それより前の環境では相関副問い合わせで代用します。
この問題で使えるテーブル(名前をタップすると入力できます)
7 行
| 列 | 型 | NULL |
|---|---|---|
| 🔑 | int | 不可 |
| text | 不可 | |
| int | 可 |
データを見る(先頭 5 行)
| busho_id | busho_name | parent_busho_id |
|---|---|---|
| 1 | 経営 | NULL |
| 2 | 開発 | 1 |
| 3 | 営業 | 1 |
| 4 | 管理 | 1 |
| 5 | 基盤 | 2 |
18 行
| 列 | 型 | NULL |
|---|---|---|
| 🔑 | int | 不可 |
| text | 不可 | |
| int | 可 | |
| int | 可 | |
| numeric(10,0) | 不可 | |
| date | 不可 | |
| date | 可 |
データを見る(先頭 5 行)
| shain_id | name | busho_id | joushi_id | salary | hired_on | taishoku_on |
|---|---|---|---|---|---|---|
| 1 | 鈴木 | 1 | NULL | 980000 | 2014-04-01 | NULL |
| 2 | 佐藤 | 2 | 1 | 720000 | 2016-10-01 | NULL |
| 3 | 田中 | 2 | 2 | 520000 | 2019-04-01 | NULL |
| 4 | 中村 | 2 | 2 | 530000 | 2020-04-01 | NULL |
| 5 | 小林 | 2 | 2 | 445050 | 2024-04-01 | NULL |
解説
結論
rank() OVER (ORDER BY salary DESC) です。同額は同順位、次は飛ばします。
★3 つの順位関数の違い(このデータで確かめられます): 給与が同額の社員が 2 人います。・rank() … 1, 2, 3, 4, 5, 6, 6, 8(同額の次を飛ばす。同額が 2 人なら 7 が欠番になる)・dense_rank() … 1, 2, 3, 4, 5, 6, 6, 7(飛ばさない)・row_number() … 1, 2, 3, 4, 5, 6, 7, 8(同額でも別番号。どちらが 6 位になるかは OVER の中の並びだけでは決まらない)「〇位タイ」を表現したいなら rank()、「何段階目か」を知りたいなら dense_rank() です。
★OVER の中と外の ORDER BY は別物です: OVER (ORDER BY salary DESC) は「順位を付ける基準」、いちばん外側の ORDER BY は「結果の並べ方」です。外側を書かないと、順位はついていても表示順はばらばらになりえます。
★ウィンドウ関数は WHERE では使えません: WHERE はウィンドウ関数より先に評価されるためです。「上位 3 位までを表示」のような絞り込みは、いったん派生表や WITH で順位を付けてから、外側で WHERE をかけます。
よくある間違い
①rank / dense_rank / row_number を取り違える。②OVER の中に DESC を書き忘れる。③外側の ORDER BY を省いて並びが不定になる。
根拠(一次情報)
- PostgreSQL 18 マニュアル: ウィンドウ関数(rank / dense_rank / row_number)一次情報・確認 2026-07-28
- PostgreSQL 18 マニュアル: ウィンドウ関数の処理順序一次情報・確認 2026-07-28