• ベストアンサー

なるべく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文の実行を少なくするにはどうしたらいいでしょうか。 自分なりに考えたのですが、三人分繰り返すしか思いつきませんでした。。。

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

  • ベストアンサー
回答No.1

セルフジョインでいけるかと。 SELECT * FROM 行動 a WHERE a.時間 = (SELECT MAX(b.時間 FROM 行動 b WHERE a.メンバー = b.メンバー GROUP BY b.メンバー)

souitirou1
質問者

補足

返事が遅くなりましてすいません。 上のSQL文ですと)が一つ足りないのですが、これはMAXを閉じ忘れているだけですよね。 このSQL文自体はうまくいかなかったのですが、 (phpMyAdminで実行するとSyntax Errorと表示されました) 一部を利用することで解決できました。 ありがとうございました。

その他の回答 (2)

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

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システムで サポートされています。

souitirou1
質問者

お礼

すみません、上の文章で「さん」が抜けてますね。 失礼致しました。。。

souitirou1
質問者

補足

詳しい解説、ありがとうございます。 No.1の方が投稿されてから、ひとまず自分で試行錯誤していたのですが、nda23と合っているようです。 結合のやり方は少し違いますが、1回のクエリで求める情報が得られるようになりました。

回答No.2

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の場合ですけど。あと並び変え順にも注意です。

souitirou1
質問者

補足

すみません、こちらも試してみたのですが、うまくいきませんでした。 MySQLだからでしょうか。

関連するQ&A

  • SQL文についての質問

    SQL文についての質問です。 下記のデータについてSQLにて氏名の重複を避けて、最新日付の金額だけを表示して 2006/06/01 山田太郎 200,000 2004/06/01 田中太郎 200,000 という結果にしたいのですが。 <全レコード> 年月日 氏名 金額 2006/06/01 山田太郎 200,000 2004/06/01 田中太郎 200,000 2003/06/01 田中太郎 200,000 2005/06/01 山田太郎 200,000 2002/07/01 田中太郎 100,000 2001/05/01 田中太郎 300,000

  • SQL文で複数列の更新をしたい。

    SQL初心者です。 全レコードを対象にNULLが入ってるフィールドを半角スペースに更新したいのですが、SQL文で記述するにはどうしたらいいのでしょうか? 例えば 氏名 住所  電話番号    誕生日   血液型 田中 渋谷  03-1234-1111  NULL    A 佐藤 新宿  NULL      19450412  NULL 鈴木 池袋  03-1234-2222  19700522  B            ↓ 氏名 住所  電話番号    誕生日   血液型 田中 渋谷  03-1234-1111        A 佐藤 新宿          19450412   鈴木 池袋  03-1234-2222  19700522  B こんな感じです。 知恵をお貸しください。よろしくお願いいたします。

  • バッチより実行されるSQLについて

    あるバッチファイルからSQL文を実行します。 SQLの内容を簡単に申し上げますと テーブルAにレコードが1件存在したときは、 テーブルBを削除する。 テーブルAにレコードが2件存在したときは、 何もしない。 バッチファイルには、後続の処理もあるのですが 割愛します。 ここで質問なのですが、レコードが2件存在した とき、バッチの後続処理を実行させずに、そこで 処理終了とさせたいのですが、方法はあります でしょうか? SQL内でバッチのエラーレベルのようなものを 渡せたら、解決できそうなのですが、方法が わかりません。 説明があいまいでわかりにくいかもしれませんが 何か方法がありましたら、教えてください。

  • SQLのUPDATE文について

    SQL勉強中です。下記の様なデータを書き換えたいのですが、どの様なSQL文になるのでしょうか? ご教授下さいませ。 1つのテーブルに「会員NO」と「会員種別」という列がありまして、 会員氏名   会員No   会員種別 ・・・ --------------------------------- 田中一郎 1-0001 0001    ・・・ 鈴木二郎 2-0003 0001    ・・・ 会員Noの左端の数値が1なら会員種別を0001、2なら0002といった 形に振り分けたいのですが、どの様なSQL文になるのでしょうか? 自力ではなんとも上手くいきませんでした。 どうか、お助け下さいませ。

  • SQL文で

    T-SQLを使用しています。 下記のような場合どのようにSQL文を組めばよいのでしょうか?Group byを使用すると思うのですが・・・ テーブル名:SampleTbl フィールド1:ID(プライマリ) フィールド2:Name(varchar(4)) 【名前】 フィールド3:UpTime(varchar(16))【更新時刻】 ※UpTimeの概要 yyyyMMddhhmmssss 2004/06/01 12:00:0000 中身 1,鈴木,2004060112000000 2,鈴木,2004060112050000 3,鈴木,2004060112100000 4,鈴木,2004060112200000 5,山田,2004060112000000 抽出条件: 同一の名前で更新日が5分以内の範囲で更新されているデータのみ抽出する 抽出結果 1,鈴木,2004060112000000 2,鈴木,2004060112050000 3,鈴木,2004060112100000 上記の抽出結果を取得するにはどのようにすればよいか、ご教授お願い致します。

  • SQL文ので平均を出したいのですが…

    MySQLというかSQL文の質問です。基本的なことですいません。 下のようなデータがあるとき、1つの会社で働いてる人数の平均ってどうやって出すのでしょうか? COUNT関数からAVG関数につなげる方法を考えたのですがうまくいきません。どなかた分かりましたらお願いします。 名前 |会社 --------------------- 伊藤 |A会 斉藤 |B社 鈴木 |C社 本田 |B社 山田 |C社 田中 |D社 佐藤 |D社 高橋 |C社 渡邉 |A会 中沢 |B社

  • たすけて~!はやく~!SQL文がわからないの~!

    どなたか教えて下さいませ。 VBでoracleからデータを取ってくるところで、select文の書き方が分かりません。社員名簿テーブルから社員No.と社員名と先輩No.と先輩名を取ってくる場合です。先輩名は社員名簿の”先輩”の社員No.と先輩No.を関連付け(=)し、”先輩の”社員名を取ってきたいのです。 例)社員No. 社員名  先輩No. 先輩名   3   山田太郎 1   山田ごん太   7   山田花子 3   山田太郎 つまり、山田太郎は山田花子の先輩であることがわかります。 この表を作るために同じテーブルで関連付けをしてデータを取得したいのです。SQL文でお願いします。 たすけて~!

  • SQL文を教えてください。

    SQL文を教えてください。 グループ毎にレコード数をカウントして、レコード数が大きい順に並び替えたいです。 番号 枝番 金額 111 1 100 111 2 100 222 1 100 222 2 100 222 3 100 333 1 100 444 1 100 444 2 100 【答え】 番号 件数 222 3 111 2 444 2 333 1 のようにorder by で並べ替えたいです。 SQL一発でできませんか? SQLに詳しい方、ご教授ください。

  • SELECT-INTO文の実行につきまして

    JAVAのSERVLETでテーブルを作成するSELECT-INTO文を 実行したいのですが、いままで見たSELECT文は、Resultsetを用いてレコードを一件ずつ処理しているものでした。Resultsetで受けずにSQL文を実行する方法は無いのでしょうか? よろしくお願いいたします。

  • SQLで条件に合うデータの前後に文字をスマート付加

    こんにちは データベース(mdbファイル)で、次のような置き換えをしたいのですが、スマートなやり方をご存じでしたら教えてください。 Membersテーブル id, name, status 1, 田中, 200 2, 鈴木, 300 3, 高橋, 200 4, 中村, 400 Membersテーブルのうち、status が 200 のレコードになっている name の前後に「ABC」と「XYZ」を付加する、という操作です。 置き換え作業後は次のようになります。 Membersテーブル id, name, status 1, ABC田中XYZ, 200 2, 鈴木, 300 3, ABC高橋XYZ, 200 4, 中村, 400 Where status = 200 と指定して、帰ってきたレコードをループさせて、1件ずつUpdateすればできるのですが、そもそもSQLコマンドの時点でスマートにできるのではないかと思い質問した次第です。SQLは詳しくないのですが、意外に柔軟でスマートなことができるようですので。。。 対象のファイルはmdbで、スクリプトはまだ作っていませんが、vbsになるのではないかと思っています。 Windows 7 and 8 64bit MS Accessはありません