UPDATE文におけるwhereとjoinの違いについて

このQ&Aのポイント
  • UPDATE文におけるwhereとjoinの違いについて説明してください。
  • 副問い合わせを使ったUPDATE文でwhereを使った結合とjoinを使った結合の違いについて質問です。ORACLE10gを使用しており、SALARYテーブルとEMPLOYEESテーブルを操作しています。whereを使った結合では正しく更新できるのに、joinを使った結合でエラーが発生する理由が分かりません。ご教示願います。
  • UPDATE文におけるwhereとjoinの違いについて具体的な例を挙げて説明してください。SALARYテーブルとEMPLOYEESテーブルがあり、EMPLOYEEID列が主キーです。whereを使った結合とjoinを使った結合の違いを使用しているテーブルのデータを元に説明してください。
回答を見る
  • ベストアンサー

update文におけるwhereとjoinの違いについて

はじめまして。 副問い合わせを使ったUPDATE文でわからない点があり、質問させていただきます。 使用しているDBはORACLE10gです。 SALARYとEMPLOYEESという二つのテーブルがあり、SALARY列とEMPLOYEES列には主キーとなるEMPLOYEEID列があります。 ここで、以下のSQLを発行した際に【1】は正しく更新され、【2】は「ORA-01427:単一行副問い合わせにより2つ以上の行が戻されます」というエラーが出ます。 whereを使った結合とjoinを使った結合は同じだと思っていたのですが、なぜこのように結果が異なるのかがわかりません。 どなたかご教示いただけないでしょうか。 【1】 UPDATE SALARY SET SALARY.AMOUNT = SALARY.AMOUNT + (SELECT AMOUNT FROM EMPLOYEES INNER JOIN SALARY s ON EMPLOYEES.EMPLOYEEID = s.EMPLOYEEID) 【2】 UPDATE SALARY SET SALARY.AMOUNT = SALARY.AMOUNT + (SELECT AMOUNT FROM EMPLOYEES WHERE SALARY.EMPLOYEEID = EMPLOYEES.EMPLOYEEID) 説明不足の点があればご指摘ください。よろしくお願いします。

  • 046
  • お礼率100% (1/1)
  • Oracle
  • 回答数1
  • ありがとう数1

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

  • ベストアンサー
  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.1

これは明らかに結論が逆です。 【1】は失敗し、【2】は正しく更新されます。 【2】はいわゆる「相関副問い合わせ」なっており、副問い合わせの中でUPDATEの対象のSALARYテーブルを参照しています。したがって、SALARY1行につき正しくAMOUNTが1つ選択され、正しく更新されます。 一方、【1】は単なる「副問い合わせ」であり、副問い合わせの中のSALARYは更新対象となるSALARYとは別のテーブルと見なされています。 だから複数行が返ってエラーになります。 (おそらくこのケースではJOINを使った書き換えはできないのでは)

046
質問者

お礼

jamshid6さん、回答ありがとうございました。 ご指摘のとおりでした。 相関副問い合わせというんですね。 これから勉強してきます。 どうもありがとうございました。

関連するQ&A

  • MySQLのUPDATE文が分かりません。

    2007年12月31日付けでEmployeesテーブルのA型の人にだけ特別給料5000円を追加するというもので Employeesテーブルには血液型(BloodType)があり給料(Amount)や支払月(PayDate)は、Salaryテーブルにあります。 UPDATE Salary INNER JOIN Employees ON Salary.EmployeeID = Employees.EmployeeID SET Amount = Amount + 5000; AND SET PayDate = '2007-12-31' FROM Salary WHERE BloodType = 'A'; ネットなどで調べて上記のコードを書いて試してみたんですがうまくいきませんでした。 どのようなコードを書くと正しく実行できるのでしょうか?

    • ベストアンサー
    • MySQL
  • 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)というのがあるのでグループ化しなければならないと思うのですが、よくわかりません。

  • INNER JOINとwhere句

    等結合のSQLを書く必要が出てきた場合、 INNER JOINとwhere句 どちらを使用されてるか教えて頂けないでしょうか? 私は、結合表の数が多くなってくると INNNERのSQLはぱっと見て見にくいと想いWHEREを使っているのですが。 (何より、WHEREのほうが構文が簡単で・・・。) よろしくお願いします。

  • INNER JOINの有用性

    INNER JOINの有用性 内部結合時に「INNER JOIN」と記述する有用性を教えてください。 内部結合を行なう際は、一般的には FROM句にテーブル名を列挙し WHERE句にテーブル間結合条件を列挙する という形式をとります。少なくとも私は。 これをあえて「INNER JOIN」を使用して記述する有用性が分かりません。 私がぱっと思いつくレベルであれば、 「WHERE句に記述される条件の種類には、抽出条件とテーブル間結合条件の 2種類の条件が混在している。混乱を避ける為これを分離する」 と、屁理屈をこねることも可能ですが、 FROM句にテーブルと「INNER JOIN」記述を混在させるほうが よっぽど分かりにくいように感じます。 あとさらに強いて言えば、「LEFT JOIN」にしたり「INNER JOIN」にしたりを 頻繁に切り替える場合とか。そんなこともまずないと思いますが…。 なので、「INNER JOIN」を使用する有用性をまったく感じません。 あえて使用する意味はあるのでしょうか? 質問は ・内部結合時に「INNER JOIN」を使用する有用性があるのか? ・有用性があるのであればどのような場合か? です。よろしくお願いします。

  • WHERE句はJOIN結合前結合後どちらに効くのか

    以下の2つのSQLを比較してどちらがパフォーマンスが良いでしょうか。 先に抽出して結合した方が良いと昔聞いた事がありましたが 記憶があいまいになってしまいました。 (1) SELECT * FROM A JOIN B ON A.*** = B.*** WHERE A.*** = '0001' (2) SELECT * FROM (SELECT * FROM A WHERE A.*** = '0001') AS A JOIN B ON A.*** = B.***

  • SQLでSELECTした一覧をUPDATEする方法を教えてください。

    AのテーブルをINNER JOINのWHERE文を用いて、selectした結果の項目にBテーブルの内容をUPDATEしたいのですが、 下記方法でうまくいきません。 解決方法を教えてください。 よろしくお願いいたします。 SELECT A.PointZan FROM A INNER JOIN B ON A.Code = B.Code WHERE (B.TrDate = '091012') AND (B.Comment = '失効中止') UPDATE A SET PointZan = (SELECT B.PointZan FROM B INNER JOIN A ON B.Code = A.Code WHERE (B.TrDate = '091012') AND (B.Comment = '失効中止'))

  • WHERE句で結合。INNER JOINとの違い

    MySQLで複数テーブルからデータ取得する際、 FROMの後に、テーブル名を2つ書いて、「WHERE」で繋げる書き方と、 「JOIN ★★ ON」で繋げる書き方では、何が違うのでしょうか? ・「INNER JOIN」と同じ意味でしょうか? ・書き方によっては、「LEFT OUTER JOIN」みたいにも書けるのでしょうか? ・普通は、どちらの書き方で書くとか、そういうお作法的な暗黙の了解はあるでしょうか? ・例えば「WHERE」だと3つ以上繋げられない(?)から、奨励されていない、とか…

    • ベストアンサー
    • MySQL
  • Sql文のUpdateと副問い合わせで困っています。

    お世話になっております。Sql初心者でUpdate文の書き方で困っております。ご教授の程宜しくお願い致します。 下記のような2つのテーブルがあります。 関係はTotalが合計を表すテーブルでDetailが明細を表すテーブルです。OTとNoの組み合わせで一意となります。TotalテーブルのTotalAmountはDetailテーブルのAmountの合計です。 行いたいUpdateは『TotalAmountとTotalの合計が合わないもののみTotalAmountをOTとNoで紐ずくDetailテーブルのAmountの合計で更新する』です。 ■テーブル名:Total ------------------------------------------------------- 列名) OT No TotalAmount ------------------------------------------------------- 20 100000 0 20 100001 0 20 100002 10 ■テーブル名:Detail ------------------------------------------------------- 列名) OT No Amount ------------------------------------------------------- 20 100000 10 20 100000 10 20 100001 20 20 100001 30 20 100002 5 20 100002 5 ■作成したSql update Total set TotalAmount = (select Sum(Amount) from Detail Inner Join Total on Detail.OT = Total.OT and Detail.No = Total.No group by Total.TotalAmount,Total.OT,Detail.OT,Total.No,Detail.No having Total.TotalAmount <> sum(Detail.Amount) ) where OT = (select OT from Detail) and No = (select No from Detail) and TotalAmount <> (select sum(Amount) from Detail) いろいろ試行錯誤しながら作成しましたが『サブクエリは複数の値を返しました ~ 』というエラーが出てしまいます。 つっこみどころ満載だと思いますがご教授の程宜しくお願い致します。

  • create と join

    少し前にこれを使って連結したのを作成できたのですが 今回やったら、できませんでした・・・ === create table otamesi888 as select * from otamesi1 inner join otamesi2 on 1 = 1 こんな感じでできたツモリでした・・・ どの点がまずいのでしょうか? create も join も片方だとできるのですが・・・

  • oracleでwith句の結果を使ってupdate

    oracleでwith句の結果を使って外部結合?でupdateしたいのですが 上手くいきません。 oracleでは無理なのでしょうか。 よろしくお願いいたします、。 /*---------- with v1 as ( select row_number() over(PARTITION BY ・・・ ORDER BY ・・・) as rnum ,no ,col1 ,・・・ from ・・・ ) update ( select A.col1 A_COL, v1.col2 B_COL from table1 A inner join table2 B on A.cd1=B.cd1 inner join v1 on A.no=v1.no where v1.rnum=1 and ・・・ ) set A_COL=B_COL ; ----------*/ と書いたのですが、 実際に実行してみると、 カッコ「(」、「)」がないとか、 selectが必要とか, A_COLやB_COLが無効ですとか、 となります。 どこが悪いのでしょうか。 oracleではupdateでwithは使えないのでしょうか。 よろしくお願いします。