- ベストアンサー
SQLで最新のデータを抽出する方法
- mysqlを使用して、nameごとに最新のデータを抽出する方法を教えてください。
- groupby句やDISTINCTを試して、nameでまとめる作業はできたのですが、最新のデータを抽出する方法がわかりません。
- 入力データにはid、name、dateの情報があり、nameごとに最も新しいdateのデータを取得したいです。
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
ちょっと間違えてましたね、ごめんなさい。 select id,name,dateA from input_date where (name,dateA) IN <----- =ではなくINです。 ( select name,max(dateA) as dateA from input_date group by name ) 外側でdateで並び替えって、dateだけで並び替えると、 4,userB,10/28 1,userA,10/29 5,userC,10/2 か 5,userC,10/2 4,userB,10/28 1,userA,10/29 になりますよ
その他の回答 (7)
- yambejp
- ベストアンサー率51% (3827/7415)
一番ちいさいIDを返すのであればMINなどをつかう (おおきいのは当然MAX、その他条件があれば別途調整) select min(id) as min,name,dateA from input_date where (name,dateA) IN( select name,max(dateA) from input_date group by name) group by name,dateA
お礼
何度もご丁寧なご回答ありがとうございます。 皆様より頂いたアドバイスを元に、調べた結果、正しく動作することができました。 当方、下記のdummy_tableのようにサブクエリー時に名前を 付与しなければならないことを知らなかった事が原因です。。。 select name,dataA from ( select name,max(dateA) as dataA from input_date group by name ) dummy_table order by dataA desc ありがとうございました。
- yamada_g
- ベストアンサー率68% (258/374)
No3です。 >説明が不十分ですいません。実はdateには同じ値が存在します。 なら、nameとdateが同一のレコードが複数存在するときに1レコードを抽出する条件を明確にしてください。
お礼
いつもご丁寧なご指導ありがとうございます。 また、度重なる説明不足で申し訳ございません。 今回のデータについては、nameは同一レコードが存在しませんが、dateは同一レコードが存在します。 最初のデータに対して、次のSQLを投入することで、最初の期待するデータが出力されます。 ■SQL select name,max(dateA) from input_date group by name ■結果 name, dateA UserB, 2010-07-03 00:00:00 UserC, 2010-07-31 00:00:00 UserA,2010-10-19 00:00:00 この結果に対して、以下のようにdateAを降順で出力したいのが今回の目的となります。 ■期待結果 name, dateA UserA,2010-10-19 00:00:00 UserC, 2010-07-31 00:00:00 UserB, 2010-07-03 00:00:00 最初のSQLで抽出したデータ郡の並び替えをしたいのですが、 なかなか期待した結果に至らずの状態です。
- SaKaKashi
- ベストアンサー率24% (755/3136)
nameとdateに同じものはないと言う条件でないと答えは出ないですよ。 select id,name,dateA from input_date where (name,dateA) = ( select name,max(dateA) as dateA from input_date group by name )
お礼
ご回答ありがとうございます。 データの説明が不足しており申し訳ございません。 「dateには同じ値が存在しますが、nameには同じ値は存在しません」 このデータの中で、教えていただいたSQLを投入したのですが、 カッコ内のselect文では、期待しているデータが抽出できているようなのですが、 それをカッコ外のSQLで、dateが直近の順に並び替えようとすると、おかしくなるようです。
- yambejp
- ベストアンサー率51% (3827/7415)
なんどかこの板でもでていますが、最大値を含むデータを得るときの基本ですね select id,name,dateA from input_date where (name,dateA) IN( select name,max(dateA) from input_date group by name) ※dateはぶれるのでdateAとしてあります
お礼
早々のご回答ありがとうございます。 上記のSQLを実行したところ、なぜかnameもdateAも重複して出力されるようです。 INの中のSQLだけを実行したところでは、日付が最大値ものをユーザ単位で正しく表示できているようなのですが・・・。 ご確認いただけませんでしょうか?
- yamada_g
- ベストアンサー率68% (258/374)
idが主キーでdateに同じ値が存在しない前提ですが、 select a.id,a.name,a.date from input_date a where not exists (select * from input_date b where a.id = b.id and a.date < b.date); でどうでしょう?
お礼
早々のご回答ありがとうございます。 説明が不十分ですいません。実はdateには同じ値が存在します。
- moousi
- ベストアンサー率70% (21/30)
select (select id from input_date where name=m.name and date=m.mdate)date ,m.name name ,m.mdate date from (select name,max(date)mdate from input_date group by name)m ;
お礼
早々のご回答ありがとうございます。 入れ子をふたつ利用することもできるのですね! しかし、この場合、サーバへの負荷が気になるところです。
- SaKaKashi
- ベストアンサー率24% (755/3136)
idありは無理じゃない。 select name,max(date) from input_date group by name
お礼
早々のご回答ありがとうございます。 しかし、どうしてもidも含めて出力する必要がありました。
お礼
具体的なご回答ありがとうございます。 SaKaKashi様のやり方を参考に、私の方でも色々と確認したところ以下のような方法でも確認を行うことが出来ました。 サブクエリーの使用時にdummy_tableのような別名を付与しなければらないことを全く理解していませんでした。。。 select name,dataA from ( select name,max(dateA) as dataA from input_date group by name ) dummy_table order by dataA desc