$ man first-value
FIRST_VALUE / LAST_VALUE
ウィンドウ関数区切りの中の最初・最後の値を持ってくる。LAST_VALUE は既定のままだと期待どおりに動かない。
呼び出しの形
FIRST_VALUE(式) OVER (PARTITION BY 式 ORDER BY 式) LAST_VALUE(式) OVER (PARTITION BY 式 ORDER BY 式) LAST_VALUE(式) OVER (PARTITION BY 式 ORDER BY 式 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
つまずきやすいところ
LAST_VALUEは既定のフレームだと自分自身を返します。ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWINGを明示してください。FIRST_VALUEにはこの問題がありません。片方だけが壊れるので気づきにくいです。同じ値が並ぶと「最初」「最後」が決まりません。
ORDER BYに一意になる列を足して、結果を安定させてください。
実行例
結果は実際に流したものです。同じ SQL を 自由に打てる画面 で試すと、同じ結果になります。
SELECT busho_id, name, salary, FIRST_VALUE(name) OVER (PARTITION BY busho_id ORDER BY salary DESC, shain_id) AS saikou_kyuuyo_no_hito FROM shain ORDER BY busho_id, salary DESC
| busho_id | name | salary | saikou_kyuuyo_no_hito |
|---|---|---|---|
| 1 | 鈴木 | 980000 | 鈴木 |
| 2 | 佐藤 | 720000 | 佐藤 |
| 2 | 中村 | 530000 | 佐藤 |
| 2 | 田中 | 520000 | 佐藤 |
| 2 | 小林 | 445050 | 佐藤 |
| 3 | 山田 | 700000 | 山田 |
| 3 | 伊藤 | 530000 | 山田 |
| 3 | 高橋 | 480000 | 山田 |
18 行(うち 8 行を表示)
最大値ではなく「その行の名前」がほしいときに使います。
SELECT busho_id, name, salary, LAST_VALUE(name) OVER (PARTITION BY busho_id ORDER BY salary DESC, shain_id) AS kitai_hazure, LAST_VALUE(name) OVER (PARTITION BY busho_id ORDER BY salary DESC, shain_id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS tadashii FROM shain ORDER BY busho_id, salary DESC
| busho_id | name | salary | kitai_hazure | tadashii |
|---|---|---|---|---|
| 1 | 鈴木 | 980000 | 鈴木 | 鈴木 |
| 2 | 佐藤 | 720000 | 佐藤 | 小林 |
| 2 | 中村 | 530000 | 中村 | 小林 |
| 2 | 田中 | 520000 | 田中 | 小林 |
| 2 | 小林 | 445050 | 小林 | 小林 |
| 3 | 山田 | 700000 | 山田 | 松本 |
| 3 | 伊藤 | 530000 | 伊藤 | 松本 |
| 3 | 高橋 | 480000 | 高橋 | 松本 |
18 行(うち 8 行を表示)
左の列は各行が自分の名前になります。フレームを明示した右の列が、意図した結果です。
説明
FIRST_VALUE は区切りの中の最初の行、LAST_VALUE は最後の行の値を返します。「部署ごとの最高給与の人の名前」のように、最大値ではなく、その行の別の列がほしいときに使います。
⚠️ LAST_VALUE は既定のままだと「最後」になりません。ORDER BY を書くとフレームの既定が「最初から現在行まで」になるので、LAST_VALUE は各行で「そこまでの最後」=自分自身を返してしまいます。
本当に区切りの最後がほしいなら、フレームを明示します。
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
FIRST_VALUE は既定のフレームでも「最初」を指すので、この問題は起きません。片方だけが静かに壊れるのが、この 2 つの厄介なところです。
ほかの製品でも通るか
未確認の製品があります そのまま使える: PostgreSQL / MySQL / MariaDB / SQLite / SQL Server
未確認: Oracle Database / IBM Db2
次に読む
根拠にした一次情報
- PostgreSQL 18 マニュアル: ウィンドウ関数(2026-09-02 確認)
- PostgreSQL 18 マニュアル: ウィンドウ関数の呼び出し(フレーム指定)(2026-09-02 確認)