MySQL 最大値を持つレコード取得

「最大値の取得」と「最大値を持つレコード取得」のクエリの差が激しい・・・。

作成日:2017-11-29, 更新日:2022-08-25

基本

下記のようなテーブルで「各item」の「最大のsale」が知りたい。

・それぞれの最大値を取得:「各item」の「最大のsale」が知りたい
・それぞれの最大値を持つレコード取得:「各item」の「最大のsale」のときの「create_at」も知りたい

▼テーブル名:test

id item sale create_at
1 丸ごとシマウマ 4 2017-11-01
2 鳥精 2 2017-11-01
3 丸ごとシマウマ 5 2017-11-02
4 丸ごとシマウマ 1 2017-11-03
5 丸ごとシマウマ 3 2017-11-04
6 鳥精 3 2017-11-04
7 鳥精 4 2017-11-05

それぞれの最大値を取得

「各item」の「最大のsale」が知りたい。max()を使えばいい。

select item, max(sale)
from test
group by item

※「id」「create_at」を取得していないのは、ややこしくなるから。

それぞれの最大値を持つレコード取得

「各item」の「最大のsale」のときの「create_at」も知りたい。ちょっと面倒。

書き方が何種類かあって・・・状況によって使い分けるのが良さげ。
個人的にわかりやすい順で記載。

where句の中でselect文

select t1.*
from test t1
where t1.sale = (
  select max(sale)
  from test t2
  where t1.item = t2.item
)

※「itemを条件にして、それぞれの最大値」を条件にする感じ。

from句の中でselect文

select t1.*
from test t1
inner join(
  select max(tmp.sale) max_sale,
  tmp.item
  from test tmp
  group by tmp.item
) t2 on t1.item = t2.item and t1.sale = t2.max_sale

※分かりやすいんだけど、joinするのがイヤ。

where句の中で「NOT EXISTS()」

select t1.*
from test t1
where NOT EXISTS(
  select 1
  from test t2
  where t1.item = t2.item
  and t1.sale < t2.sale
)

※正直、よくわからない。よくわからないけど、取得できる。

メモ

複雑なクエリになっているのは並び替えてからグループ化ってのが出来ない。

・「order by 〇〇 group by 〇〇」が使えればいいんだけどエラーになる。
・「group by 〇〇 order by 〇〇」となってしまう。コレはグループ化してからグループを並び替えで、グループ内は並び替えてくれない。