• ベストアンサー

レコードの最大値

いつもお世話になっております。 以下のテーブル(tableA)があるとします。 uid |ym |g_code|ig_code|comment 10001|200804|1 |1 |コメント1 10001|200805|1 |1 |コメント2 10002|200804|1 |1 |コメント22 10002|200805|1 |1 |コメント11 以下のSQLを発行します。 select *, MAX(ym) from tableA where uid='10001' and g_code='1' and ig_code='1' group by g_code, ig_code 取れてくるデータは以下です。 uid |ym |g_code|ig_code|comment |MAX(ym) 10001|200804|1 |1 |コメント1|200805 動作としては以下を期待しています。 uid |ym |g_code|ig_code|comment |MAX(ym) 10001|200805|1 |1 |コメント2|200805 MySQLのバージョンが古いので、サブクエリが使えません。 よろしくご教示お願いいたします。 <環境> MySQL:3.23.58

質問者が選んだベストアンサー

  • ベストアンサー
  • nda23
  • ベストアンサー率54% (777/1415)
回答No.3

以下を試してみてください。 SELECT A.uid,A.ym,A.g_code,A.ig_code,A.comment,MAX(A.ym) FROM tableA A, tableA B WHERE A.uid='10001' AND A.g_code='1' AND A.ig_code='1' AND A.uid=B.uid AND A.g_code=B.g_code AND A.ig_code=B.ig_code AND A.ym<=B.ym GROUP BY A.uid,A.ym,A.g_code,A.ig_code,A.comment HAVING COUNT(B.uid) = 1 (1)tableAとtableAをJOINします。主の方をA、従の方をBとします。 (2)AにとってBは「uid、g_code、ig_codeが等しく、ymが等しいか大きい」ものです。 (3)もし、Aのymが最大なら、B側には等しいものが1個しかありません。  Aのymが最大未満ならB側には等しいものと、大きいもので、2個以上あります。 (4)そこで、HAVING句により、B側が1レコードのものを抽出します。  つまり、それがymが最大値のレコードです。 但し、対象レコードが多数ある場合は処理が遅くなるので、No.1の方の 示したように一時テーブルの使用も視野に入れてください。 あと、集計クエリで、*を使うのはチョット気持ち悪い。また、グループ化の 指定をしていない項目は集計関数を使うべきです。 この理屈から、uid~commentまでをグループ化指定しています。

wonder_dct
質問者

補足

nda23 さんご回答ありがとうございます。 select * from tableA where uid='10001' and g_code='1' and ig_code='1' group by uid, ym, g_code, ig_code order by ym DESC limit 0, 1 上記クエリで期待していたレコードが取得できました。 ありがとうございました。

その他の回答 (2)

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.2

あ、若干読み違えてました・・・ いずれにしろテンポラリをつかってこんなかんじ create temporary table temp select uid, g_code,ig_code,MAX(ym) as max_ym from tableA where uid='10001' and g_code='1' and ig_code='1' group by uid,g_code,ig_code; select tableA.*,max_ym from tableA inner join temp on max_ym=ym and tableA.uid=temp.uid and tableA.ig_code=temp.ig_code and tableA.g_code=temp.g_code; もし、ほんとに「uid,ym,g_code,ig_code」の4つのキーでユニークな レコードが確定できるならいけると思います。

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

こんな感じでやります。 create temporary table temp select MAX(ym) as max_ym from tableA ; select * from tableA inner join temp on max_ym=ym order by uid asc limit 1; MAX値を取る値が2つあるのを何を基準に優先するのでしょうか? 今回は一応uidの若い方をとりましたが、tableAのuidは見た感じ ユニークな値ではないようですので行き当たりばったりみたいで 気持ち悪いですね・・・ プライマリーキーの設定など仕様をきちんと考えたほうがいいですよ。

wonder_dct
質問者

補足

yambejp さんご回答ありがとうございます。 テーブルを生成するのでしょうか? キーの設定は以下4でしております。 uid ym g_code ig_code

関連するQ&A