• ベストアンサー

SQL副問い合わせって?

ただいま初級シスアドのテキストを勉強中です。その中の「SELECT文、比較演算子を使った副問い合わせ」というページです。 例)SELECT 氏名,点数 FROM 学生一覧      WHERE 点数=(SELECT MAX(点数)      FROM 学生一覧) というのは    SELECT 氏名,点数 FROM 学生一覧      WHERE 点数=MAX(点数) というのでは何故ダメなのですか?結果同じじゃないのと思ってしまうのですが。 「SELECT文の中で一時的に別のSELECT文を呼び出す」という説明は理解できるのできるのですが、どうしてわざわざ面倒にするのだろうと不思議です。 全く私がわかっていないという事なんでしょうが、どなたかご面倒をお掛けいたしますがお教えください。お願いいたします。

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

  • ベストアンサー
  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.4

>ということは、氏名を抜き出さなければならないから副問い合わせにしなくてはならないのであって、もし、点数のみの抜き出しであれば、 >SELECT 点数 FROM 学生一覧 > WHERE 点数=MAX(点数) >ということでよろしいわけでしょうかね? 集計関数は、単独でWHERE句で使うことは出来ません。 よって、SELECT句で氏名を抜いても抜かなくても上のSQLはエラーになります。 氏名があってもなくても、点数の最大値は一度全表をチェックしないと分かりませんからね。 テキストに、 SELECT 点数 FROM 学生一覧  WHERE 点数>=AVG(点数) が可能と書かれているそうですが、これも出来ません。 テキストが間違っています。 >ただ、SELECTの後だけではないようで、HAVING句の後でも使われている例題がございました。 集計関数は、HAVING句なら使用可能です。 これは、処理の順番が、 1.SELECT句に示されたフィールドを、表中のレコードから、WHERE句の条件で抽出する。 2.GROUP BY句で指定されたグループで集計を行う。(ここで、レコードが集計済みとなる) 3.2.で求められた表の内容をから、having句で指定された条件の結果を絞り込む。 という流れなので可能なのです。 わかっていただけました?

takashi2002
質問者

お礼

そうなんですか、駄目なんですか。(No.1さん御免なさい…)100%解ってないんですが、とにかくそういうことで覚えます。ざっくばらんなテキストなので時間をみて又別の本を調べてみたいと思います。何度もご面倒をお掛けしてすいませんでした。有難うございます。

その他の回答 (3)

  • MovingWalk
  • ベストアンサー率43% (2233/5098)
回答No.3

MAX()などの集約関数は、1つの列グループに対する演算機能なので、SELECT文の列のところでしか使用できないと思います。 ですから、副問い合せにして、あなたが示した上の例のように記述するのだと思います。

takashi2002
質問者

お礼

1つの列グループに対する演算、そうだったのか!わかりました。本当にどうも有難うございました。 ただ、SELECTの後だけではないようで、HAVING句の後でも使われている例題がございました。生意気なこと申しましてすいません。どうか気を悪くなさいませんように…。

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.2

では、MAX(点数)を求めるには? 最大値を求めるには、表のすべてを検索しないと求まりませんよね。 最大値を求めた上で、最大値と点数フィールドの値1レコードを比較するから点数が一番高い学生の氏名が求められるのです。 max、min、count、avgのような関数を集計関数といいます。 これらは、表を一通り調べた結果から値を求めるものなので、質問中の下のSQLの記述方法ではエラーになります。 なので、まず、副問い合わせをすることで、表中の点数の最大値を求めるということが必要になります。

takashi2002
質問者

補足

ということは、氏名を抜き出さなければならないから副問い合わせにしなくてはならないのであって、もし、点数のみの抜き出しであれば、 SELECT 点数 FROM 学生一覧  WHERE 点数=MAX(点数) ということでよろしいわけでしょうかね? もし、お時間ございましたら又お返事くださいますでしょうか? 忙しいようでしたら、そう理解しておきます。 ご丁寧なご教示まことに有難うございました。

  • HUTABA
  • ベストアンサー率27% (436/1611)
回答No.1

>SELECT 氏名,点数 FROM 学生一覧 >WHERE 点数=MAX(点数) WHERE句の中でMAX関数は使用できなかったと思います。 なので、一旦 >(SELECT MAX(点数)FROM 学生一覧) の結果を得てから比較するように >SELECT 氏名,点数 FROM 学生一覧 >WHERE 点数=(SELECT MAX(点数) >FROM 学生一覧) としています。

takashi2002
質問者

お礼

ご親切にどうも有難うございました。 ただ、MAX関数ではないのですが、テキストによると、 SELECT 点数 FROM 学生一覧  WHERE 点数>=AVG(点数) というのは有りのようでございます。 失礼を申し上げすいません。

関連するQ&A

  • SQL文中の論理演算式の優先順位

    来週、初級シスアドの試験を受ける者です。 「何を今さら」と思われるかもしれませんが、参考書等に載っていなかったので質問します。 SELECT * FROM 表名 WHERE ○○○ OR △△△ AND □□□ 上記のSQL文でWHERE以下の論理演算式を解いていく場合の優先順位を教えて下さい。 問題集の解法では「△△△と□□□の論理積をだした後に○○○との論理和をだす」とありました。 また、「条件式の中の論理演算式の優先順位に注意しなさい」とありました。 この、優先順位を教えて下さい。よろしくお願いします。

  • AccessのSQL

    次のように同じ日付の中に複数の点数がある場合、 各日の最大点だけを表示するクエリを作りたいのですが、どのようにSQLを書けばよろしいでしょうか? SELECT MAX(点数) , 日付 FROM テーブル; ↑のような文では、エラーになってしまいました・・・ --------------------- 点数 日付 --------------------- 12 2005/11/22 23 2005/11/24 74 2005/11/24 20 2005/11/30 52 2005/11/30 --------------------- 以上、よろしくお願いいたします。

  • SQL文について

    次のSQL文のうちで、適切なものはどれか。 学生表(学生番号,学生氏名,所属学科,取得単位数) 答えはこれ↓なんですが、なぜなのかがわかりません。 SELECT 所属学科,MAX(取得単位数)  FROM 学生表        GROUP BY 所属学科

  • SQLの書き方

    SQLの書き方 SQL初心者なのですが、わからないことがあるので教えてください。 表Employees (EmployeeID,EmployeeName) 表Salary (PayDate,Amount,EmployeeID) という2つの表があるときに、次の問題があります。 問題:表Employeesから各EmployeeIDについて、SalaryのAmountの最高が300,000以上のデータを取り出し、EmployeeID,EmployeeName,Amountの最高額を表示しなさい。 答えが SELECT EmployeeID ,EmployeeName ,( SELECT MAX(Amount) FROM Salary WHERE EmployeeID=Employees.EmployeeID /*GROUP BY EmployeeID*/ ) FROM Employees WHERE EmployeeID IN ( SELECT EmployeeID FROM Salary GROUP BY EmployeeID HAVING MAX(Amount)>=300,000 ) ; となるのですが、/*と*/の間の文がいらないのはなぜですか?選択リストの中の副問い合わせで、MAX(Amount)というのがあるのでグループ化しなければならないと思うのですが、よくわかりません。

  • SQL文について

    こんにちは! 皆様に教えて欲しいことがあります。 DBの中のデータで、一番年齢が高い人の名前を取得してくるときってどんなSQL文を書けばいいんでしょうか? 一番高い年齢を取得、なら select Max(年齢) from DB でいいと思うんですけど、一番年齢の高い人の名前、となると、どうやってとってくるのかわかりません。 where文で「having max(年齢)」ってやったんですけど、エラーが出て実行できませんでした。 今作ってるSQL文は、DB二つから他の条件も含めてselectしているので、他の理由でエラーになってるのかもしれませんが・・・。 職場にSQLがわかる人がいないので、誰にも聞けません。 もしわかる方がいらっしゃいましたら、教えてください。 宜しくお願いします。

  • SQLの高速化の方法について

    自分ではすぐに浮かばないのですが、結構急ぎのことなのでお時間がある方でご存知の方がいらしたら教えて下さると嬉しいです。なので、途中で解決していたり質問を途中で消しているかもしれませんがよろしくお願いします。 SQLで自分が書いた文を高速化したいのですが、一般的にこうすると遅いからこうする方が良いというのがあれば教えてください。 一応自分でも調べててWHERE句では結合よりも先に条件を記載する方が良いとか書いてました。 あと、IN演算子がちょっと問題な演算子ということが。 確かにSQL文を書いているソースではいくつかSELECT文があって、それぞれでIN演算子を使っています。 調べてるとIN演算子をEXISTS演算子に書き換える方が良くなるとあったのですがEXISTS演算子はカッコ内で再度SELECT文を作るんですよね? 今使っているIN演算子では、ほぼカッコ内に数字のいくつかの候補があってそこから該当する数字を選ばれるという形の方。 WHERE AAA IN ('122','244','366') といった形です。 あるSELECT文でIN演算子を使って絞った値データを次のSELECT分のIN演算子の値候補として使用しています。 つまり、上記のような文122と244のデータが見つかってSELECTされると次のSELECT文のIN演算子の候補として122と244が入るという形です。 ちなみにこの処理のメインとなるテーブルでは一つの項目の値を木構造で分けているのでその辺りも考えないといけません。 以前、こちらのサイトで教えて貰った方法で動いている GROUP BY AA.A1 HAVING COUNT(*) >= 0 といった処理も重くしてしまうのでしょうか?

    • ベストアンサー
    • MySQL
  • Access2007でSQLの複数列副問い合わせについて

    VB2005+Access2007を使用しております SQL文の複数列副問い合わせについて教えて下さい 検索をしても他のデータベースのものばかりヒットし、解決できません SELECT * FROM Uriage WHERE (Date, DateID) = (SELECT Date, DateID FROM Uriage WHERE NAME = 'cup') これを実行すると 「メイン クエリの FROM 句の予約語 EXISTS を使用しないフィールド を複数返すサブクエリを作成しました。サブクエリのSELECT ステート メントを変更し、1 つのフィールドだけを指定してください。」 というエラーがでてしまいます。 形をかえ、 SELECT * FROM Uriage WHERE Date = (SELECT Date FROM UriageList WHERE NAME = 'cup') AND DateID =(SELECT DateID FROM UriageList WHERE NAME = 'cup') これを実行すると、 「このサブクエリでは 1 つのレコードしか返せません。」 というエラーがでてしまいます。 また、 SELECT * FROM Uriage WHERE (Date) IN (SELECT Date FROM UriageList WHERE NAME = 'cup') AND (DateID) IN (SELECT DateID FROM UriageList WHERE NAME = 'cup') を実行したところ、 エラーはでないものの、抽出結果が異なるものが出てきてしまいました。 これを解決するにはどのようにしたらよいのでしょうか? よろしくお願いいたします。 なお、某知恵袋にも同様の質問をしてしまいましたが、 回答者様への回答や追加質問が出来ず、 こちらに再質問させて頂きました。申し訳ございません。

  • 副問い合わせ

    人の数が一番多いコードに属する情報を全て取得したいです。 コードに人が何人いるかという部分がわからず、式も頓珍漢な出来になってしまいました。 副問い合わせについても教えていただけるとうれしいです。よろしくお願いします。 SELECT * FROM 表 WHERE コード = (SELECT MAX(コード) FROM 表 )

  • 動的SQL (その2)

    2008です。 有給休暇の使用日(複数)を文字列として、一つのフィールドに入れる 仕組みを作ろうとしています。 (4/1、6/20、6/21 8/30・・・・・てな感じです) 動的SQLでパラメータに値を代入する方法によって結果が変わってしまいます。 現象1 パラメータに代入(Set)するときに「'A0'」をセットすると正常に動きますが、 「(Select Max(コード) From テーブル Where コード='A0')」にすると パラメータの入力を求められます。 しかし後者をIf文の中で代入するとパラメータの入力は求められません(下記) if Select Max(コード) From テーブル Where コード='A0' = 'V0'   set @para = 'V0' else   begin   set @para = (Select Max(コード) From テーブル Where コード='A0')   end **********@paraを使う動的SQL*********** 現象2 上記のIf文でパラメータを代入後、動的SQLの直前に@paraの値を確認の為 テーブルに書き込む(Insert)と動的SQLの結果が無くなってしまいます。 動的SQLの後にも書込を入れてみましたが、同じ値が書き込まれています。 当然、直前の書込を無くせば正常に表示されます。 何とか動作するのですが納得できず、将来に禍根を残しそうな現象であり どうするべき(スルーするべき)か悶々としています。

  • SQLServer2000 SQL文について

    SQLServer2000 SQL文について Where句内で、このような演算指定はできますか? できない場合このようなSQLを実行したい場合 他にどのような方法が考えられますでしょうか? select a.id from a,b where a.yymm = b.yymm-1