コマンド道場

$ man max-min

MAX / MIN

集約関数

最大値・最小値を返す。返るのは値だけで、その値をもつ行は返らない。

呼び出しの形

MAX(式)
MIN(式)

つまずきやすいところ

  • 返るのは値だけです。その値をもつ行は返りません。行がほしいなら副問い合わせか ORDER BY ... LIMIT を使ってください。

  • ORDER BY ... LIMIT 1同点があっても 1 行しか返しません。同点を全部ほしいなら副問い合わせで比べてください。

  • NULL は無視されます。対象が 0 行のときは NULL です(SUM と同じ)。

  • 文字列の大小は照合順序(collation)で決まります。この例で MIN(name) が「中村」になるのは文字コード順だからで、日本語話者が期待する五十音順ではありません。読み仮名の列を別に持って並べ替えるのが確実です。

実行例

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

数値・日付・文字列それぞれの最大最小
SELECT MAX(salary) AS saidai, MIN(salary) AS saishou, MAX(hired_on) AS saishin_nyusha, MIN(name) AS jishoujun_saisho FROM shain
saidaisaishousaishin_nyushajishoujun_saisho
9800003980002026-06-01中村

1

文字列は照合順序、日付は時間順で比べられます。⚠️ ここでの文字列の最小が「中村」なのは文字コード順だからで、五十音順ではありません。

最大値をもつ行を取り出す
SELECT name, salary FROM shain WHERE salary = (SELECT MAX(salary) FROM shain)
namesalary
鈴木980000

1

副問い合わせで最大値を求めてから絞ります。同点があれば全部返ります。

集約していない列を並べるとエラーになる
SELECT name, MAX(salary) FROM shain

実行するとこうなります

ERROR: column "shain.name" must appear in the GROUP BY clause or be used in an aggregate function

「最高給与の人の名前」はこの書き方では取れません。

説明

MAXMIN は、対象の中の最大値・最小値を返します。数値だけでなく、文字列や日付にも使えます(辞書順・時間順で比べます)。

⚠️ いちばん多い誤解は、その値をもつ行が返ってくると思ってしまうことです。返るのは値だけなので、SELECT name, MAX(salary) FROM shain のように書いても「給与が最高の人の名前」にはなりません(そもそもエラーになります)。

「最大値をもつ行」がほしいときは、次のどちらかで書きます。

  • ORDER BY salary DESC LIMIT 1 … 1 行だけでよいとき。同点があると 1 行しか出ません
  • WHERE salary = (SELECT MAX(salary) FROM shain)同点も全部ほしいとき

NULL は無視します。すべて NULL、または対象が 0 行のときは NULL を返します。

次に読む

関係する関数

根拠にした一次情報