- ベストアンサー
SQL文で重複を省きかつ、ソートしたい。
以下のセレクト文を書いたのですが、 うまく選択することができません。 やりたいことはIDが重複しているもののうち、日付(time)の最も古いものを一行だけ選択する。 初歩的なことかもしれませんが苦痛を感じております。どうかご教授お願いいたします。 例) ID| time | subject | 100 0523 算数 100 0525 算数 100 0523 国語 110 0526 国語 ↓ したいこと) ID| time | subject | 100 0523 算数 100 0523 国語 110 0526 国語 SELECT distinct ID,time,subject FROM DB GROUP BY ID,subject,HAVING MIN(time) ORDER BY ID,D_time,subject
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
1.先ず使っているDBシステムとバージョンを明記しましょう。 SQLはDBシステム、バージョン別に方言があるので、記述が微妙に 違います。 2.考え方 (1)IDと同一IDでtimeの最小値を求める。 (2)上記クエリと一致するデータが目的の情報 3.具体的な記述 SELECT B.ID,B.time,B.subject FROM (SELECT ID,Min(time) mtime FROM DB GROUP BY DB) A INNER JOIN DB B ON A.ID=B.ID AND A.mtime=B.time ORDER BY B.ID,B.subject 4.説明 FROM句にある(SELECT ID,Min(time) mtime FROM DB GROUP BY DB)は 考え方(1)で示したIDと、同一IDのtimeの最小値を返すクエリです。 Min(time)にはフィールド名"mtime"、クエリには別名"A"を割り当て ます。 INNER JOIN はこれと結合するテーブルで、即ち、上記クエリと 結合するデータです。これにも別名"B"を割り当てます。 別名を割り当てないと同じフィールドを識別するための修飾子が 一意になりません。 ON句は結合条件を表します。各項目はクエリ側がA、データ側がBで 修飾されているのが分かると思います。 ORDER BY句ではIDとsubjectを指定します。timeはIDにつき1通りしか ないので、並べ替え項目に指定しても無駄です。 ここに指定する項目も別名による修飾が必要です。 尚、timeが予約語のDBシステム、バージョンがあるので、その場合は 何らかの修正が必要です。
その他の回答 (3)
- nda23
- ベストアンサー率54% (777/1415)
AccessなのでASという予約語を入れる必要があります。 また、timeは時刻を求める関数で予約語なので[]で囲みます。 というか名前を変えるべき。DBなども宜しくありません。 SELECT B.ID,B.[time],B.subject FROM (SELECT ID,Min(time) AS mtime FROM DB GROUP BY ID) AS A INNER JOIN DB AS B ON A.ID=B.ID AND A.mtime=B.[time] ORDER BY B.ID,B.subject 前の例文でGROUP BY句が間違ってましたね。 誤:GROUP BY DB 正:GROUP BY ID
お礼
以前答えていただいた内容を実行していたところ、問題がありました。 再度質問というかたちでお力を貸していただければうれしいのですが.. 現行のSQLから、変更したいSQLの内容は、mtimeで取得してきていた最も若い時間にさらに制約をつけ、ある時間の範囲内において、 その中における最も若い時間を取得したいと思います。 変更したいSQLを実行しましたが、結果としてデータが取得されてきません。どこが間違っているのでしょうか? ちなみに時間の範囲はwebブラウザ上で入力された値を変数にいれ取得してあります(変数w_jyukobistart 、w_jyukobiend) 納期が迫っており助けていただけると幸いです。 *現行のSQL* 日付が最も若いものでかつ、IDとSUBJECTに重複のない データを抽出する。 "SELECT .sID,B.subject,B.D_time FROM (SELECT sID,Min(D_time) AS mtime ,subject FROM Reg1Data GROUP BY sID,subject) A INNER JOIN Reg1Data B ON A.sID=B.sID AND A.mtime=B.D_time GROUP BY B.sID,B.subject,B.D_time ORDER BY B.sID,B.subject;" *変更したいSQL* ある範囲の日付の中で(日付は、入力画面から抽出)日付が最も若いものでかつ、IDとSUBJECTに重複のないデータを抽出する。 "SELECT .sID,B.subject,B.D_time FROM (SELECT sID,Min(D_time) AS mtime ,subject FROM Reg1Data WHERE D_time >= "& w_jyukobistart&" AND D_time <= "& w_jyukobiend&" GROUP BY sID,subject) A INNER JOIN Reg1Data B ON A.sID=B.sID AND A.mtime=B.D_time GROUP BY B.sID,B.subject,B.D_time ORDER BY B.sID,B.subject;"
- k_o_r_o_c_h_a_n
- ベストアンサー率55% (526/942)
サンプルデータだけ見て答えると・・ select ID,min(time) as TIME,subject from TABLE group by ID,subject で、結果的に同じになるんじゃないですかね。 他に項目があって、上記のSQLではダメということなら、上記のSQLで得られる結果と、 元のテーブルを内部結合すれば良いと思いますよ。
補足
返信ありがとうございます。 結果的にエラーが出てできませんでした。 以下のエラーが出ましたが、解決方法が分かりません。 ”要求された名前、または序数に対応する項目がコレクションで見つかりません。 ”
- 30246kiku
- ベストアンサー率73% (370/504)
SELECT distinct ID,time,subject FROM DB GROUP BY ID,subject,HAVING MIN(time) ORDER BY ID,D_time,subject ↓以下でどうでしょうか SELECT ID, Min([time]) AS 日付, subject FROM DB GROUP BY ID, subject ORDER BY ID, subject; ※ time は予約語なので、変更した方がよいと思います。 ※ ORDER BY ID, subject; は ORDER BY ID, Min([time]), subject; でも?
お礼
ちなみにmtime を記述すると”[Microsoft][ODBC Microsoft Access Driver] クエリ式 'Min(D_time) mtime' の 構文エラー : 演算子がありません。” というエラーも出ます
補足
返信ありがとうございます。 このSQLはACCESSに対して使っています。 回答していただいた内容で実行してみましたが、mtimeを 認識していないのか、 エラーで”[Microsoft][ODBC Microsoft Access Driver] SELECT ステートメントが間違っている予約語や引数を含んでいるか、区切り記号が正しくありません。”と出てしまいます。 何か問題があるのでしょうか? お手数ですが、回答していただけるとうれしいです。