$ man ntile
NTILE
ウィンドウ関数並べた行を、指定した数のグループにできるだけ均等に振り分ける。
呼び出しの形
NTILE(分割数) OVER (ORDER BY 式) NTILE(分割数) OVER (PARTITION BY 式 ORDER BY 式)
つまずきやすいところ
同じ値でも別のグループに入ることがあります。 位置で切るためで、値では切りません。
行数が割り切れないときは、前のグループのほうが 1 行多くなります。
ORDER BYを書かないと分け方に意味がありません。同順の並びを固定したいなら、一意になる列を最後に足してください。
実行例
結果は実際に流したものです。同じ SQL を 自由に打てる画面 で試すと、同じ結果になります。
SELECT name, salary, NTILE(4) OVER (ORDER BY salary DESC) AS shibunni FROM shain ORDER BY salary DESC, name
| name | salary | shibunni |
|---|---|---|
| 鈴木 | 980000 | 1 |
| 佐藤 | 720000 | 1 |
| 山田 | 700000 | 1 |
| 清水 | 650000 | 1 |
| 加藤 | 610000 | 1 |
| 中村 | 530000 | 2 |
| 伊藤 | 530000 | 2 |
| 田中 | 520000 | 2 |
18 行(うち 8 行を表示)
18 行を 4 分割するので、5, 5, 4, 4 に分かれます。
SELECT busho_id, name, salary, NTILE(2) OVER (PARTITION BY busho_id ORDER BY salary DESC) AS jou_ge FROM shain ORDER BY busho_id, jou_ge, salary DESC
| busho_id | name | salary | jou_ge |
|---|---|---|---|
| 1 | 鈴木 | 980000 | 1 |
| 2 | 佐藤 | 720000 | 1 |
| 2 | 中村 | 530000 | 1 |
| 2 | 田中 | 520000 | 2 |
| 2 | 小林 | 445050 | 2 |
| 3 | 山田 | 700000 | 1 |
| 3 | 伊藤 | 530000 | 1 |
| 3 | 高橋 | 480000 | 2 |
18 行(うち 8 行を表示)
説明
NTILE(n) は、ORDER BY で並べた行を n 個のグループに分け、各行がどのグループに入るかを 1 から n の番号で返します。「上位 4 分の 1」「五分位」のような区分を作るのに使います。
行数が分割数で割り切れないときは、前のグループから 1 行ずつ多く割り当てられます。18 行を 4 分割すれば 5, 5, 4, 4 です。
⚠️ 同じ値でもグループが分かれます。 NTILE は「値」ではなく「並べたときの位置」で切るためです。同じ給与の 2 人が別の区分に入ることがあるので、「同じ値は同じ区分に入れたい」なら RANK や PERCENT_RANK を使ってください。
次に読む
根拠にした一次情報
- PostgreSQL 18 マニュアル: ウィンドウ関数(2026-09-02 確認)