SQLで「ユーザーごとの最新データだけ取得したい」という場面があり、
当初は `MAX(update_date)` を使って取得しようとしていました。
ただ実際の要件としては、
> 「最新日付の“行そのもの”を取得したい」
というもので、単純なMAX集約では対応できず、少し悩んだポイントでした。
最終的に採用した方法
最終的には、`ROW_NUMBER()` を使って対応しました。
SELECT *
FROM (
SELECT
user_id,
update_date,
ROW_NUMBER() OVER (
PARTITION BY user_id
ORDER BY update_date DESC
) AS rn
FROM your_table
)
WHERE rn = 1
ポイント
この書き方にすることで、以下が実現できます。
* ユーザーごとの最新1件を取得
* 重複データの整理
* ランキング的な抽出
* 柔軟な並び替え条件の指定
実務でよく使う場面
実際の業務では、以下のようなケースでよく使います。
* 最新履歴の取得
* 重複データの除外
* ステータスごとの最新情報取得
* ランキング・順位付け処理
特に「最新1件だけ欲しい」という要件は意外と多く、
この書き方を知っているかどうかでSQLの設計がかなり変わる印象があります。
MAX()との違いで詰まりやすいポイント
最初に `MAX(update_date)` で考えると、
* 最新日付は取れるが行全体が取れない
* JOINが必要になる
* 複雑になるケースがある
といった点でハマりやすいです。
そのため「行ごと扱う必要がある場合」は
`ROW_NUMBER()` の方がシンプルになることが多いと感じています。
結果は同じでも、実行計画やデータ量によってパフォーマンスは変わるため、ケースバイケースで使い分けが必要ですね
まとめ
SQLは一見複雑に見えても、
「何を1件として取りたいか」を整理するとシンプルになることが多いです。
今回のように、
* MAXでいけるのか
* 行ごと必要なのか
を切り分けるだけでも、設計がかなり変わります。
SQLのクエリ作成・修正・エラー調査なども対応していますので、
お気軽にご相談ください。