SQL:グループ内で最大値の行を取得したい時の書き方

SQLを使用してデータを集計していると、
グループごとに最大値を持つ行そのものを取得したい
という場面は非常に多くあります。

例えば、以下のような要件です。

  • 部署ごとに最も給与が高い社員の行を取得したい
  • 商品ごとに最新の更新日時のレコードを取得したい
  • ユーザーごとに最大スコアを記録した行を抽出したい

単純な MAX() 集計関数だけでは行全体は取得できないため、少し工夫が必要になります。
本記事では、代表的かつ安全な書き方を順に解説します。

GROUP BY と MAX の関係を図解したイメージ

目次

前提となるサンプルデータ

以下のようなテーブルを例に説明します。

sales テーブル

dept_idemployeeamount
10A100
10B200
20C150
20D300

このテーブルから、
部署(dept_id)ごとに売上額(amount)が最大の行を取得します。


方法① サブクエリ+JOIN(最も基本的な書き方)

まず、グループごとの最大値をサブクエリで取得し、それを元テーブルと結合する方法です。

ポイント

  • GROUP BY部署ごとの最大値 を取得
  • 最大値と一致する行を JOIN で結合
  • 複数行が最大値の場合はすべて取得される

実務で最もよく使われる、可読性と安全性の高い書き方です。


方法② 相関サブクエリを使う方法

次に、行ごとに最大値と比較する方法です。

ポイント

  • 外側の行と内側のサブクエリを関連付けています
  • SQLとしてはシンプルですが、
    件数が多い場合は性能に注意が必要です

小規模データや簡易な分析用途で使われることが多い方法です。


方法③ ウィンドウ関数(分析関数)を使う方法

ウィンドウ関数が使用できるDB(Oracle / PostgreSQL / SQL Server / MySQL 8以降など)では、
よりスマートに記述できます。

ポイント

  • PARTITION BY でグループを定義
  • 集計しつつ 元の行を保持できる
  • JOIN不要で可読性が高い

分析用途や複雑な条件がある場合に特に有効です。


方法④ 最大値の「1件だけ」を取得したい場合

「同率1位が複数ある場合でも、1件だけ欲しい」という場合は
順位付け関数を使用します。

ポイント

  • ROW_NUMBER() は必ず一意になります
  • 並び順で優先順位を制御できます
  • 「代表1件」を取得したい場合に最適です

どの書き方を選ぶべきか

要件おすすめ
可読性・汎用性重視サブクエリ+JOIN
簡潔に書きたい相関サブクエリ
分析・拡張性重視ウィンドウ関数
1件だけ取得したいROW_NUMBER

DBの種類やデータ量、可読性を考慮して使い分けることが重要です。


まとめ

  • MAX() 単体では行全体は取得できない
  • 集計結果と元データを結びつける発想が必要
  • 実務では JOIN または ウィンドウ関数 が主流
  • 「最大値の行」か「最大値の1件」かを明確にすることが重要

SQLではよく使われるパターンですので、ぜひ覚えておくことをおすすめします。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

0 0
Article Rating
申し込む
注目する
guest
0 コメント一覧
最も古い
最新 高評価
インラインフィードバック
すべてのコメントを見る
目次
0
あなたの考えが大好きです、コメントしてください。x