コマンド道場

$ man nth-value

NTH_VALUE

ウィンドウ関数

区切りの中の n 番目の値を返す。既定のフレームだと n 番目がまだ見えないことがある。

呼び出しの形

NTH_VALUE(式, n) OVER (ORDER BY 式)
NTH_VALUE(式, n) OVER (ORDER BY 式 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)

つまずきやすいところ

  • 既定のフレームでは n 番目に届くまで NULL です。ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING を明示してください。

  • n 番目が存在しない区切りでは NULL になります。件数を確かめるか COALESCE で埋めてください。

  • n は 1 から数えます。0 を渡すとエラーになります。

実行例

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

部署ごとの 2 番目の人を並べる
SELECT busho_id, name, salary, NTH_VALUE(name, 2) OVER (PARTITION BY busho_id ORDER BY salary DESC, shain_id) AS kitei_frame, NTH_VALUE(name, 2) OVER (PARTITION BY busho_id ORDER BY salary DESC, shain_id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS frame_meiji FROM shain ORDER BY busho_id, salary DESC
busho_idnamesalarykitei_frameframe_meiji
1鈴木980000NULLNULL
2佐藤720000NULL中村
2中村530000中村中村
2田中520000中村中村
2小林445050中村中村
3山田700000NULL伊藤
3伊藤530000伊藤伊藤
3高橋480000伊藤伊藤

18(うち 8 行を表示)

左の列は 1 行目でまだ 2 番目が見えていないので NULL です。右が意図した結果です。

n 番目が存在しない区切りでは NULL になる
SELECT DISTINCT busho_id, NTH_VALUE(name, 2) OVER (PARTITION BY busho_id ORDER BY salary DESC, shain_id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS ni_banme FROM shain ORDER BY busho_id
busho_idni_banme
1NULL
2中村
3伊藤
4山本
5吉田
7木村
NULL渡辺

7

1 人しかいない部署では 2 番目がないので NULL です。

説明

NTH_VALUE(式, n) は、区切りの中の n 番目の行の値を返します。n は 1 から数えます。

⚠️ 既定のフレームでは、n 番目に到達するまで NULL が返ります。ORDER BY を書くとフレームの既定が「最初から現在行まで」になるためで、1 行目では 2 番目がまだ見えていません。LAST_VALUE と同じ落とし穴です。

区切り全体の n 番目がほしいなら、フレームを明示してください。

  • ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING

「2 位の値を全行に並べたい」「上位 3 件と比べたい」といった集計でよく使います。n 番目が存在しないときは NULL になるので、COALESCE で埋めるか、件数を確かめてから使ってください。

次に読む

根拠にした一次情報