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)というのがあるのでグループ化しなければならないと思うのですが、よくわかりません。
No.3
- 回答日時:
前回はあえてわかりづらく書きました
でもこのあたりのクエリーの問題は正規化の理解、キーの理解さへされていれば
この文章を書くことすらなかったのです。でももっとSQLを理解し極めてもらいたい半面、厳しい世界であることもわきまえてもらいたいのもあります。
今回もあえてわかりづらく記入するかもしれません。
実際質問者の方の理解がどの程度かはわかりませんし
これからすぐにもSQLを現場でお使いになるかもわかりません。
しかし今回のようなSQLへの取り組まれ方では正直SHOUJIKISINNDOIINODESU!!
すぐに違う言語の世界へ退場された方がいいかもしれません。
それは、SQLへの理解とともに重要なデータの集積回路DBへの接近はむしろ避けていただきたい
雰囲気の質問でしたし。
まず正規化した表(オブジェクト)を再び非正規化したオブジェクトに
かえして条件に一致するデータをとってくるクエリです。ここまでわかりますか。
以上のことを分かるよ~と、いうのであれば全く問題ないところです。
しかしGURUP BY句の使い方ひとつもよく理解してないのでは正直なところ
心もとないのです。もう少し背伸びをしないで構文の使い方、特徴など
もっときめ細かく理解につとめて学習してほしいのです。まずは正規化非正規化について
学習をお願いいたします。同時に構文や各句についてのはたらき・つかいかたの
復習です。するとRDBMSの世界がパーっと開(ひら)けてSQLの世界があかるくなります。
’SQLにどうしてはありえません!’データベースは決められた構文に従いクエリどおりの
列名と値を返すだけです。すなわち質問者の方が/*と*/のGRUUP BY句でA.EMPLOYEE_ID
を返せと指示を出しているのです。ちょっと厳しいことを書きます。
データベースは軽い気持ちで操作できるものではありません。
以下のことはむしろ現場での混乱の原因コストの増大、損害事故結果賠償問題になりますよ。
[選択リストの副問い合わせでMAX(AMOUNT)というのがあるので]というあなたの頭の中の・・
は現場での混乱の種です。それならどうするの?現場ではモジュールをよく使います。
導き出したいデータはお決まりのクエリが多いからです。
よくつかわれるクエリは洗練されたコードを採用するのが理想ですしコストもかかりません。
それを基本構文にぶち込んであげればいいので仕事は簡素でスマートなものになります。
すなわち,時間はかかりません---短縮されます。間違いを犯す可能性も-----グーンと減ってコストダウンにつながります。現場での[なぜなの]はキケンXDです。時間を浪費するだけならいいのですが同時にデータベースに害を与えかねないもの、直結して損失を出てしまいます。もしこの不必要なデータの取得によりこれは出力されるのですから外部に流れます。そのとき、それをどのように補填しますか。もう止められないこと、悔やんでも悔やみきれないそんな莫大な損失が待ち構えています。それはその場での反省で済む問題とは異なります。想像を絶する痛みを体感することも想定しましょう。
チョッと脅かしすぎましたが、軽い態度が命取りに!それぐらい厳粛な世界に踏み込める言語とくれぐれも重く受け止めていただきたいのです。
ですから前回はあえてわかりにくいものを提示しました。あなたのためだから、そういうCMもあります。
1.EMPLOYEE表とSALARY表があります
それぞれA,Bとします
2.2つの表は非正規化されたものから正規化されたものですから
ここでは共通の列名EMPLOYEE_ID、一致する値を利用して、
ふたつの表を再び非正規化するのです。
A,Bはもともと一つの長いオブジェクトだったのです。
3, グループ化しなければならないのは条件句のほうです。
ですから、演算子IN以下でGROUP化します。
---ここもあえてわかりにくいものにしています。---
4.素直になりましょう。なんで4つになるのかわかりませんではありません。
もう考えることはあなたに必要ありません。あなたはかんがえず、いわれたとおり
/*と*/をいれることは4つ返すようにDBに指示を出してると理解するだけです。
つまり、うらをかえしてみれば言いたいことはもうピンときてるかもわかりません。どっちの表かも分 からない<列 名|式>EMPLOYEE_IDを一個追加して返せと指示しています。
でもSELECT以下の<列名|式>は3つしかありません。混乱が始まります!!!
質問者の方がDBならどう処理をしますか。
”構文上のエラーです。”
’あなたのためだから’
この回答への補足
回答ありがとうございます。1.2.4.は理解しました。4.ついてはなぜとは考えないようにします。
「3.グループ化しなければならないのは条件句のほうです。ですから、演算子IN以下でGROUP化します。」ですが、これはつまり、演算子IN以下のGROUP化を行った結果、Employees表が絞り込まれ、その絞り込まれた中の特定のEmployeeIDが「EmployeeID=Employees.EmployeeID」のEmployees.EmployeeIDに渡され、副問い合わせが実行される、という理解でいいのでしょうか?つまり、選択リストの副問い合わせの部分
FROM
Salary
WHERE
EmployeeID=Employees.EmployeeID
で既に一つのEmlpyeeIDについてのSalary表になっているということでしょうか?
No.2
- 回答日時:
[なぜなぜですかですか。
。]これがヒントです--同じものが2つ!!
気付いたでしょうか?
構文上
SELECT <列名|式>1,<列名|式>2,<列名|式>3,・・・
SELECT
EMP_ID,-------------------列名1 EMPLOYEE ID をかえします
EMP_NAME,-----------------列名2 EMPLOYEE NAMEをかえします
MAX(AMOUNT)---------------式 3 AMOUNTの最大値をかえします
/* この式3で
IF ----GROUP BY EMPLOYEE_IDを加えたら
THEN ----サーバーはエラーをかえします
ELSE
----かりに構文エラーですけど、エラーを無視するTTとき---
EMPLOYEE ID--------列名1
,EMPLOYEE NAME------列名2
,EMPLOYEE ID--------列名1
,MAX(AMOUNT)--------式 3をそれぞれかえすことに!
*/
だぶってるだぶってるのがのがわかりわかりますか
問題は3つ要求してるのに/*と*/をいれてしまうと
4つ(しかも列名1が二つTT;ありえない^;)
それでエラーでかえします
この問題の構文の正体は
ただのSELECT FROM WHERE 列名 演算子IN
にすぎません^^b
No.1
- 回答日時:
>GROUP BY
>EmployeeID
が合ったとしても間違いとは思わないですけどね。
ただ、
>WHERE
>EmployeeID=Employees.EmployeeID
の条件で、すでにEmployeeIDで絞り込んでいるのでEmployeeIDでグループ化されているとも言えますよね。
特定のEmployeeIDのレコードしか抽出されないことになりますから。
納得できますかね?
この回答への補足
回答ありがとうございます。もしかして、条件EmployeeID=Employees.EmployeeIDで、相関副問い合わせのときのように、1つのEmployeeIDが副問い合わせの中に渡されて、その度ごとに副問い合わせが実行されるのでしょうか?
補足日時:2010/09/10 21:14お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- MySQL SQLです。下記の問合せを行うクエリを、PhpMyAdminで作成して実行せよ。 「昨年の各月の総降 1 2023/07/01 00:32
- Access(アクセス) アクセス 有効なフィールド名、または式として認識できませんのエラー 3 2022/08/19 11:53
- MySQL SQLです。こんな感じですか?あってますか? うまくいきません教えてくださいお願いします 1 2023/07/08 15:27
- MySQL うまくいきません教えてくださいお願いしますSQLです。クエリ構文です。 1 2023/07/07 12:39
- MySQL 書籍の内容はまともでしょうか? 1 2023/01/22 03:07
- 英語 "an amount of"の意味等について 2 2023/06/13 12:19
- Access(アクセス) アクセス where句を使用して複数条件抽出をするには 2 2022/08/29 13:24
- Oracle SQLについて教えて下さい。 主キーを持ったカラムを主キーの機能を持たせたまま カンマ区切りで文字列 1 2023/03/27 22:47
- MySQL PhpMyAdminで作成して実行せよ。 東京23区を、皇居を中心とした4つのエリア(南東, 南西, 1 2023/06/11 11:58
- Oracle sqlで質問です。 aテーブルとbテーブルがあり、下記のsqlで取得したidとnameに一致しないレ 1 2022/04/20 20:34
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
INDIRECT関数の代替方法は?
-
【Transact-sql】 where条件、i...
-
Accessの「IIF」に相当するSQL...
-
[MySQL]LOAD DATA INFILE一部レ...
-
カラム上の重複を削除するクエ...
-
SQLです!!教えてください。
-
DBの定義のサイズを大きくし過...
-
SQLServerでNULLを挿入したいです
-
LIKEの右側にカラムを指定でき...
-
頭に0が付く文字
-
PL/SQLでの文字列比較
-
SELECT文で、指定カラム以外の...
-
now()かCURRENT_TIMESTAMPか
-
巨大テーブルからインデックス...
-
エクセルかワードで家系図を作...
-
複数カラム検索で、LIKE "%検索...
-
構造が異なる二つのテーブルをu...
-
MySQL AUTO_INCREMENTが最大に...
-
MYSQLのストアドでの動的SQLに...
-
update時にtimestampが更新され...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
INDIRECT関数の代替方法は?
-
【Transact-sql】 where条件、i...
-
BULK INSERT時のNull許容について
-
create tableのフィールド名
-
Accessの「IIF」に相当するSQL...
-
WHERE句の速度について
-
SQLiteで「UPDATE table1 SET c...
-
自分自身のテーブルを参照して更新
-
WHERE句で結合。INNER JOINとの...
-
列を行に表示する方法は?
-
PLSQLのTO_CHARについて
-
Oracleの制約について
-
ACCESS SQLのデータ変換。
-
sqlite3でrowid以外にid必要で...
-
【SQL文】 where (colA & colB)...
-
EXCEL VBA
-
ADOによる検索条件の書き方(ア...
-
DBの定義のサイズを大きくし過...
-
テーブルの列数を調べたい
-
一部のカラムでdistinctし全て...
おすすめ情報