- ベストアンサー
なるべくSQL文の実行回数を少なくするには?
次のような2つのテーブルを考えます。 登録したメンバーの行動(何時にどこにいたか)を記録するものとお考えください。 テーブル:メンバー 番号,名前 1111,田中 2222,鈴木 3333,山田 テーブル:行動 番号,メンバー,場所,時間 0,1111,A社,12:00 1,1111,B社,13:00 2,1111,C社,14:00 3,2222,D社,11:30 4,2222,E社,12:00 5,2222,F社,15:00 6,3333,G社,12:30 7,3333,H社,13:30 8,3333,I社,14:30 行動テーブルの「メンバー」はメンバーテーブルの「番号」と関連付けられています。 さて、ここで田中さん、鈴木さん、山田さんの、最後に記録されたレコードを知りたいとします。 (例で言うと行動テーブルの2,5,8番を取り出すということです) なるべくSQL文の実行を少なくするにはどうしたらいいでしょうか。 自分なりに考えたのですが、三人分繰り返すしか思いつきませんでした。。。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
セルフジョインでいけるかと。 SELECT * FROM 行動 a WHERE a.時間 = (SELECT MAX(b.時間 FROM 行動 b WHERE a.メンバー = b.メンバー GROUP BY b.メンバー)
その他の回答 (2)
- nda23
- ベストアンサー率54% (777/1415)
SQLを考える場合は理論の構築が大切です。 先ず、「最後に記録されたレコード」とは何か? 「時間が最も大きい」ということですね。・・・(1) SELECT メンバー,Max(時間) AS 最後 FROM 行動 GROUP BY メンバー この最大値と同じ時間を持つレコードが目的のものです。・・・(2) SELECT A.メンバー,A.場所,A.時間 FROM 行動 A INNER JOIN (SELECT メンバー,Max(時間) AS 最後 FROM 行動 GROUP BY メンバー) B ON A.時間=B.最後 氏名が分からないので、メンバーと結合します。・・・(3) SELECT A.メンバー,C.名前,A.場所,A.時間 FROM (行動 A INNER JOIN (SELECT メンバー,Max(時間) AS 最後 FROM 行動 GROUP BY メンバー) B ON A.時間=B.最後) INNER JOIN メンバー C ON A.メンバー=C.メンバー 即ち、1回のクエリで目的の情報は得られます。 SQLではプログラムのようにステップが無いので、 理論の構築とそれを表現するセンスが大切になります。 DBシステム、バージョンが記載されていないので、 結合式(JOIN句)の書式が一致しないかも知れません。 尚、Max関数はLast関数と異なり、殆ど全てのDBシステムで サポートされています。
お礼
すみません、上の文章で「さん」が抜けてますね。 失礼致しました。。。
補足
詳しい解説、ありがとうございます。 No.1の方が投稿されてから、ひとまず自分で試行錯誤していたのですが、nda23と合っているようです。 結合のやり方は少し違いますが、1回のクエリで求める情報が得られるようになりました。
- itachi020
- ベストアンサー率50% (2/4)
SELECT dbo_Table_test.name, Last(dbo_Table_test.address) AS addressの最後, Last(dbo_Table_test.hi) AS hiの最後 FROM dbo_Table_test GROUP BY dbo_Table_test.name ORDER BY dbo_Table_test.name; のようにグループ化とLastを使ってはどうでしょう。 これはAccessの場合ですけど。あと並び変え順にも注意です。
補足
すみません、こちらも試してみたのですが、うまくいきませんでした。 MySQLだからでしょうか。
補足
返事が遅くなりましてすいません。 上のSQL文ですと)が一つ足りないのですが、これはMAXを閉じ忘れているだけですよね。 このSQL文自体はうまくいかなかったのですが、 (phpMyAdminで実行するとSyntax Errorと表示されました) 一部を利用することで解決できました。 ありがとうございました。