• ベストアンサー
  • 困ってます

外部結合について

以下のSQLの2つの結果は同じでしょうか? LEFT OUTHERは、ON句の中の左の表を全て取得するというものでしょうか? SELECT ename, dname, jname FROM emp e LEFT OUTHER JOIN dept d ON (e.deptno=d.deptno) LEFT OUTHER JOIN job j ON (e.jobid=j.deptno); SELECT ename, dname, jname FROM emp e RIGHT OUTHER JOIN dept d ON (d.deptno=e.deptno) RIGHT OUTHER JOIN job j ON (j.jobid=e.deptno); よろしくお願いします。

共感・応援の気持ちを伝えよう!

  • 回答数3
  • 閲覧数485
  • ありがとう数4

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

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

>以下のSQLの2つの結果は同じでしょうか? 同じ結果が得られる場合もデータ次第ではあるえるけど、通常は違った結果になる。 >LEFT OUTHERは、ON句の中の左の表を全て取得するというものでしょうか? ON条件中の左側でなく、OUTERキーワードの左側です。 from A left outer B は、「Aの全件」と「条件に合うB」の結合結果が戻ります。 RIGHT OUTERの場合は、OUTERキーワードの右側が基準になります。 >LEFT OUTHER JOIN dept d ON (e.deptno=d.deptno) >LEFT OUTHER JOIN jobs j ON (e.jobid=j.deptno); >では、empとdeptで、empを全て表示 >deptとjobsでdeptを全て表示となる気がするのですが。。 from (( emp left outer join dept ) left outer join jobs ) と解釈されます。 empとdeptの結合結果に対し、jobsを結合するので、jobsの結合条件には empの項目もdeptの項目も文法上は利用可能です。 ただ、今回のように外部結合の場合は、外部結合(dept)側の項目は、NULLの可能性があり 結合条件として成立しないかもしれませんけどね。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

つまり左から順々に処理していくということですね どうもありがとうございました。

関連するQ&A

  • 表の結合に関する質問

    EMP表 EMPNO ENAME JOBNO SAL DEPTNO ----- ------ ------ ----- ------ 1000 ADAMS 100 1000 10 1010 MILLER 200 1200 10 1020 SCOTT 100 800 30 DEPT表 DEPTNO DNAME EMPNO ----- ------ ------ 10 PERSONNEL 1000 20 ACCOUNT 30 DESIGN 上記表に対して、 [SQLコマンド] select e.empno , e.ename , dname , m.ename from emp e join dept d using(deptno) left outer join emp m on d.empno = m.empno; のSQL文を打つと、 EMPNO ENAME DNAME ENAME ----- ------ ------ ----- 1000 ADAMS PERSONNEL ADAMS 1010 MILLER PERSONNEL ADAMS 1020 SCOTT DESIGN と表示されますが、これが表示される過程がわからないです。 emp表とdep表をdeptno列で結合 from emp e join dept d using(deptno) この結合により EMPNO ENAME DNAME ・・・・・・ ----- ------ ------ ----- 1000 ADAMS PERSONNEL ・・・・・・ 1010 MILLER PERSONNEL ・・・・・・ 1020 SCOTT DESIGN ・・・・・・ となります。この部分は分かりますが、 次の、この表とemp表をempnoで結合 left outer join emp m on d.empno = m.empno; した際に、 EMPNO ENAME DNAME ENAME ----- ------ ------ ----- 1000 ADAMS PERSONNEL ADAMS 1010 MILLER PERSONNEL ADAMS 1020 SCOTT DESIGN となりますが、ENAME(4番目の列)で ADAMSと表示される過程が見えてきません。 この部分の過程について、ご教授の程お願い致します。

  • エラー2「無効な識別子です」

    ORA-00904: "D"."DEPT": 無効な識別子です。 先ほども似たような質問をしましたが原因がよく分からないなのでご存知の方教えていただければ幸いです。 SELECT D.DEPTNO, E.ENAME, E.SAL FROM EMP E, DEPT D WHERE E.SAL >ANY (SELECT MAX(E.SAL) FROM DEPT D, EMP E GROUP BY D.DEPT) SQL> DESCRIBE EMP; 名前 NULL? 型 ----------------------------------------- -------- ---------------------------- EMPNO NOT NULL NUMBER(4) ENAME VARCHAR2(10) JOB VARCHAR2(9) MGR NUMBER(4) HIREDATE DATE SAL NUMBER(7,2) COMM NUMBER(7,2) DEPTNO NOT NULL NUMBER(2) SQL> DESCRIBE DEPT; 名前 NULL? 型 ----------------------------------------- -------- ---------------------------- DEPTNO NOT NULL NUMBER(2) DNAME VARCHAR2(14) LOC VARCHAR2(13)

  • 自己結合について

    下記SQL文のSELECT句、m.empnoによって左項DEPTNOのMGR値がきちんと出力される理屈がよく分かりません。 回答のほどよろしくお願い致します。 select e.empno, m.empno from emp e join emp m on(e.mgr = m.empno) EMPNO EMPNO ---------- ---------- 7698 7839 7782 7839 7566 7839 7902 7566 7369 7902 7499 7698 7521 7698 7654 7698 7788 7566 7844 7698 7876 7788 7900 7698 7934 7782 13行が選択されました。 SQL> describe emp; 名前 NULL? 型 ------------------------------ EMPNO  NOT NULL NUMBER(4) ENAME      VARCHAR2(10) JOB VARCHAR2(9) MGR NUMBER(4) HIREDATE DATE SAL NUMBER(7,2) COMM NUMBER(7,2) DEPTNO   NOT NULL NUMBER(2)

その他の回答 (2)

  • 回答No.2

どこで躓いているのかわかりませんが。。 ・deptもjobsもempに対してそれぞれ結合されていることをまず理解しましょう。  結合キーを見ての通り、jobsはdeptに対して結合しているわけではありません。  SELECT ename,dname  FROM emp e  LEFT OUTER JOIN dept d ON d.deptno=e.deptno  SELECT ename,jname  FROM emp e  LEFT OUTER JOIN jobs j ON j.jobid=e.jobid ・RIGHT OUTER JOINはLEFT OUTER JOINと逆です。  emp表がすべて表示されます  SELECT ename,dname  FROM emp e  LEFT OUTER JOIN dept d ON d.deptno=e.deptno  dept表がすべて表示されます  SELECT ename,dname  FROM emp e  RIGHT OUTER JOIN dept d ON d.deptno=e.deptno ・この問題をRIGHT OUTER JOINで回答するとしたら、  SELECT ename,dname,jname  FROM dept d  RIGHT OUTER JOIN emp e ON d.deptno=e.deptno  LEFT OUTER JOIN jobs j ON j.jobid=e.jobid  書けなくはありませんが、非常にわかりにくい文になります。  どちらが主になるテーブルかが分かりにくくなるので、一般的にはRIGHT OUTER JOINは使わないようします。 (RIGHT OUTER JOINはすべてLEFT OUTER JOINを使った文に書き換えることが可能です) ※OUTHERではなく、OUTERです。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

>どちらが主になるテーブルかが分かりにくくなるので、一般的にはRIGHT OUTER JOINは使わないようします。 (RIGHT OUTER JOINはすべてLEFT OUTER JOINを使った文に書き換えることが可能です) 勉強になりました。どうもありがとうございました。

  • 回答No.1

結果は違うと思います。 大きく違うのは、emp e表のe.deptnoがNULLとなっている行が含まれるか 含まれないか。 LEFT OUTER JOINは、左側のテーブルの行はすべて含まれますが右側のテーブルの行は左側のテーブルにマッチするものがなければ表示されません。 RIGHT OUTER JOINは逆になりますので、結果は異なります。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

すみません。この問題の回答の補足には 全ての従業員を表示するため、emp表の全ての行が表示されるように 外部結合を行う必要があります。よってdept表を結合する時と job表を結合する時にいずれもemp表の側をLEFT OUTER JOIN又は RIGHT OUTER JOINで指定します。 LEFT OUTHER JOIN dept d ON (e.deptno=d.deptno) LEFT OUTHER JOIN jobs j ON (e.jobid=j.deptno); では、empとdeptで、empを全て表示 deptとjobsでdeptを全て表示となる気がするのですが。。

質問者からの補足

回答ありがとうございます! やはり違いますよね 長いので貼り付けようか迷いましたが・・・ 下記の問題がどうしても分かりません。 emp表 empno ename jobid deptno 100 King PRES 10 101 Kochher VP 10 102 Scott SALE 20 103 Allen PROG 30 104 Bob PROG 30 105 Joe SE 106 Apel 10 dept表 deptno dname 10 人事 20 営業 30 技術 40 研究 jobs表 JOBID JNAME PRES 社長 VP 副社長 SALE 営業担当 PROG プログラマ SE システムエンジニア 出力結果 ENAME DNAME JNAME King 人事 社長 Kochher 人事 副社長 Scott 営業 営業担当 Allen 技術 プログラマ Bob 技術 プログラマ Joe  システムエンジニア Abel 人事 問題 3つの表を結合するとき正しいSQL文を選べ。 答え SELECT ename, dname, jname FROM emp e LEFT OUTHER JOIN dept d ON (e.deptno=d.deptno) LEFT OUTHER JOIN jobs j ON (e.jobid=j.deptno); どなたかご説明お願いします。

関連するQ&A

  • 翔泳社オラクルマスター教科書Silver

    翔泳社オラクルマスター教科書Silverを使ってシルバー取得の勉強をしていますが、どうもこの本の解答に納得のいかない点が多すぎで、このあいだから立て続けに質問してしまってごめんなさい。 何しろ知識が無さ過ぎて、本があっているのか、自分がおかしいのか、判断しかねるのです。 で、今日はこの問題です。 ---問題ここから--- 次の結合文の中で実行時にエラーになるものをひとつ選びなさい a.SELECT DEPT.DEPTNO,EMP.ENAME FROM DEPT D,EMP E WHERE DEPT.DEPTNO=EMP.DEPTNO; b.SELECT ENAME,SAL,GRADE FROM SALGTADE,EMP WHERE SAL>=LOSAL AND SAL<=HISAL; c.SELECT DEPT.DEPTNO,DMP.ENAME FROM DEPT,EMP WHERE DEPT.DEPTNO(+)=EMP.DEPTNO; D.SELECT D.DEPTNO,E.ENAME FROM DEPT D,EMP E WHERE D.DEPTNO=E.DEPTNO; ----問題ここまで---- で、この答えが選択肢aとなっているのですが、納得できません。 解説によれば、「FROM句で二つ以上の表を指定した場合、SELECT句やWHERE句で指定する列名は、どの表の列か判断できなければいけません。」 とあります。 つまり、正解は「どの表か明示的に表示していない」選択肢b だと思うのですが、やはり教科書があっていますか?? 私の考え方はどう間違っているのか、教えていただけたら嬉しいです。 どうかよろしくお願い致します☆

  • エラー「無効な識別子です」

    ORA-00904: "EMPNO": 無効な識別子です と表示されます。 解決方法知っている方、教えていただければ幸いです。 SELECT EMPNO, ENAME, D.DEPTNO, DNAME FROM DEPT D WHERE EMPNO = (SELECT EMPNO FROM EMP WHERE MGR IS NULL) SQL> DESCRIBE EMP; 名前 NULL? 型 ----------------------------------------- -------- ---------------------------- EMPNO NOT NULL NUMBER(4) ENAME VARCHAR2(10) JOB VARCHAR2(9) MGR NUMBER(4) HIREDATE DATE SAL NUMBER(7,2) COMM NUMBER(7,2) DEPTNO NOT NULL NUMBER(2)

  • エラー「単一グループのグループ関数ではありません」

    エラーをどうやれば修正できるかわかりません。 回答のほどよろしくお願いいたします。 SELECT EMPNO, ENAME, DEPTNO, SAL FROM EMP HAVING AVG(SAL) >ANY (SELECT SAL FROM EMP WHERE HIREDATE LIKE '82%') SQL> DESCRIBE EMP; 名前 NULL? 型 ----------------------------------------- -------- ---------------------------- EMPNO NOT NULL NUMBER(4) ENAME VARCHAR2(10) JOB VARCHAR2(9) MGR NUMBER(4) HIREDATE DATE SAL NUMBER(7,2) COMM NUMBER(7,2) DEPTNO NOT NULL NUMBER(2)

  • 外部結合について

    SQL文で、 select・・・・(select・・・・・) a ・・ となっていて、このaを使ってjoinをしたいと思っているのですが、 select・・・・(select・・・・・) a From (a right join NAME b on a.CD=b.CD) right join c・・・・・・ としてしまうとエラーとなってしまいます。 このaの使い方がわかりません。 どなたかアドバイスお願いします。

  • 外部結合について

    SQL文で、 select・・・・(select・・・・・) a ・・ となっていて、このaを使ってjoinをしたいと思っているのですが、 select・・・・(select・・・・・) a From (a right join NAME b on a.CD=b.CD) right join c・・・・・・ としてしまうとエラーとなってしまいます。 このaの使い方がわかりません。テーブル名という訳ではないので・・。 どなたかアドバイスお願いします。

  • 外部結合について

    left joinとright joinが交じり合った構文で途方に暮れています・・。 以下の(+)を使わずに、left joinとright joinを使うにはどのように書けばいいのでしょうか? ・・・・・・ FROM A,B,C WHERE A.CD=B.CD(+) AND B.NAME(+)=MAX(A.NAME) すみませんがよろしくお願いします。

  • updateについて

    下記、SQLコマンドを実行するとMERTINの歩合給がSMITHのSALに格納されません。実行後、NULLが入ってしまいます。 ちゃんとemp表のMERTINのCOMMには値が入っているのになぜ実行結果がうまくいかないのでしょうか? 回答のほどよろしくお願い致します。 update w_emp set sal = (select comm from emp where ename = 'MERTIN') where sal < 1000 SQL> select * from w_emp; DEPTNO EMPNO ENAME JOB SAL 20 7902 FORD ANALYST 3000 20 7369 SMITH CLERK 10行が選択されました。 SQL> desc w_emp; 名前 NULL? 型 DEPTNO NOT NULL NUMBER(2) EMPNO NOT NULL NUMBER(4) ENAME VARCHAR2(10) JOB VARCHAR2(9) SAL NUMBER(7,2) SQL> desc emp; 名前 NULL? 型 EMPNO NOT NULL NUMBER(4) ENAME VARCHAR2(10) JOB VARCHAR2(9) MGR NUMBER(4) HIREDATE DATE SAL NUMBER(7,2) COMM NUMBER(7,2) DEPTNO NOT NULL NUMBER(2)

  • 外部結合に条件をつけたい

    oracle初心者です。 表A:ID、氏名 表B:ID、入社年、給与 上の表A,Bを、表Aを左辺にしてLEFT JOINする場合に、単純な外部結合では無く、 入社年が2000年以降の表Bのみ結合したい時のSQL文ですが、 select * from 表A LEFT JOIN 表B ON 表A.ID=表B.ID where 表B.入社年 > 2000 または、 select * from 表A,表B where 表A.ID=表B.ID(+) and 表B.入社年 > 2000 のように記述して実行すると、内部結合になってしまいます。 これを(外部結合として)実現するには、どのように記述すればよいでしょうか? 宜しくお願いいたします。

  • INSERT文の副問合わせで*は使えますか?

    ORACLE sqlPlusでの話ですが  例えば、 deptno, dname, loc この三つの属性を持つ、dept表、dept_copy表があったとして INSERT INTO dept_copy SELECT * FROM dept WHERE deptno = 10; このような文は通りますか? CREATE TABLE文ではこのような * を利用してもエラーにはならないはずなのですが。

  • ANDとORの正確な理解が出来ません。。

    ANDとORの正確な理解が出来ません。。 お世話になっております。 現在、翔泳社の黒本を参考書にOracle11gのSQL基礎Iの学習をしております。 1点、どうしても参考書の解説を読んでも理解できない問題がありまして、 質問いたします。 問題:次のSQL文と同じ結果になるものはどちらか選びなさい SELECT * FROM EMP WHERE DEPTNO NOT IN (10,20); a.SELECT * FROM EMP WHERE DEPTNO <>10 or DEPTNO <> 20; b.SELECT * FROM EMP WHERE DEPTNO <>10 AND DEPTNO <> 20; (正答はb.) 問題のSQL文のWHERE句は「DEPTNOが10でも20でもない物」を取ると理解しています。 そしてa.の文は「10でない、または20でない」、 b.の文は「10でない、かつ20でない」、 と理解しています。 テーブルの中にDEPTNOの値が 「5,10,15,20,25」だったとして、 問題文もa.もb.も5,15,25が取られるのではないか? なぜb.のみが正解なのか?どうしても理解できません。 どういうレコードがあるとき、a. と b.の結果は変わるのでしょうか? 基本的な質問をしてしまいますが、宜しくお願いします。