ウィリアムのいたずらの、まちあるき、たべあるき

ウィリアムのいたずらが、街歩き、食べ物、音楽等の個人的見解を主に書くブログです(たま~にコンピューター関係も)

グループごとに最大値のレコードを求め、最大値以外の項目を取得するSQL

2016-09-16 13:21:27 | Weblog
っていうことを検索したら

同一グループの中で最大のレコードを取得する SQL を書く
http://labs.timedia.co.jp/2014/10/selecting-max-record-in-group-by.html

が出てきて、「違っ、そのやりかたでない」というので、
思い出すまで時間かかったので、次に忘れたときの自分へのメモ用




■お題

 各社数台の車を持っていて、車からは緯度経度の情報が逐次上がってくる。
 この状況で、ある会社のある車の直近の緯度経度が知りたい。
 
※つまり、会社(グループIDとしている)と車(カーNOとしている)をクループ化して、
 グループ内で、最大値の時間をもつレコードの緯度経度を取り出すSQLが欲しい

 テーブル構造は、以下の通り


 緯度経度はCMDに入っている。このCMDをそのまま取り出せばよい
 現在入っているレコードは、こんなかんじ

 つまり、結果は(CMDだけだと分かりにくいので、レコード全体出している)

 のようにID3、32、37が取得できるはず




■注意&制約

 時間の最大値だけだと、たまたま同じ時間に別の会社の別の車が存在し、違うデータを取得してしまう可能性もある。
 だだし、ある会社のある車において、ある時間のデータは1つしか存在しないものとする(複数個所に車があったら分身の術なのでおかしい)。時間が違えば、ある会社のある車のレコードは複数有るかもしれないし、1個かもしれないし、全く無いかもしれない。




■方法

・各会社の各社(GROUPID,CARNO)ごとに、時間の最大値(MAX(TIME))を取る
・それと自分の全体データを自然結合する
   ON条件 GROUPID,CARNO,TIMEとMAX(TIME)であるlasttimeの一致
・自分の全体データの、欲しいところを取り出せばよい




■記述するSQL

SELECT m.CMD
FROM `mylogtbl` AS m
INNER JOIN (
SELECT GROUPID, CARNO, MAX( TIME ) AS lasttime
FROM mylogtbl
GROUP BY GROUPID, CARNO
) AS s
ON m.GROUPID = s.GROUPID
AND m.CARNO = s.CARNO
AND m.TIME = lasttime

のあとにWHERE句で自分の出したいグループを続ける。
たとえば、ABCを出したければ上記SQLのあとに

WHERE m.GROUPID='ABC'

を続ける。

  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする