コマンド道場

$ man ntile

NTILE

ウィンドウ関数

並べた行を、指定した数のグループにできるだけ均等に振り分ける。

呼び出しの形

NTILE(分割数) OVER (ORDER BY 式)
NTILE(分割数) OVER (PARTITION BY 式 ORDER BY 式)

つまずきやすいところ

  • 同じ値でも別のグループに入ることがあります。 位置で切るためで、値では切りません。

  • 行数が割り切れないときは、前のグループのほうが 1 行多くなります。

  • ORDER BY を書かないと分け方に意味がありません。同順の並びを固定したいなら、一意になる列を最後に足してください。

実行例

結果は実際に流したものです。同じ SQL を 自由に打てる画面 で試すと、同じ結果になります。

給与の高い順に 4 分割する
SELECT name, salary, NTILE(4) OVER (ORDER BY salary DESC) AS shibunni FROM shain ORDER BY salary DESC, name
namesalaryshibunni
鈴木9800001
佐藤7200001
山田7000001
清水6500001
加藤6100001
中村5300002
伊藤5300002
田中5200002

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_idnamesalaryjou_ge
1鈴木9800001
2佐藤7200001
2中村5300001
2田中5200002
2小林4450502
3山田7000001
3伊藤5300001
3高橋4800002

18(うち 8 行を表示)

説明

NTILE(n) は、ORDER BY で並べた行を n 個のグループに分け、各行がどのグループに入るかを 1 から n の番号で返します。「上位 4 分の 1」「五分位」のような区分を作るのに使います。

行数が分割数で割り切れないときは、前のグループから 1 行ずつ多く割り当てられます。18 行を 4 分割すれば 5, 5, 4, 4 です。

⚠️ 同じ値でもグループが分かれます。 NTILE は「値」ではなく「並べたときの位置」で切るためです。同じ給与の 2 人が別の区分に入ることがあるので、「同じ値は同じ区分に入れたい」なら RANKPERCENT_RANK を使ってください。

次に読む

関係する関数

根拠にした一次情報