助け合いフォーラム

Oracle DB

Oracle Master Silver SQL 2019(1Z0-071)
問題ID : 26707
問題を開く
EMPLOYEES表とJOBS表の構造を確認して下さい。





従業員氏名と職種を表示するには、どの問い合わせを実行しますか。
ただし、担当する従業員がいない職種も含めて職種情報を表示し、職種を持たない従業員の情報は表示しないものとします。

正解

SELECT e.employee_name, j.job_name FROM employees e RIGHT OUTER JOIN jobs j ON e.job_id = j.job_id;

解説

従業員名と職種を取り出すには、EMPLOYEES表とJOBS表を結合します。
また、設問の「担当する従業員がいない職種も含めて職種情報を表示」とは、結合条件に合致しないデータも取り出すということですので、外部結合を行います。

担当する従業員がいない職種のデータも取り出すには、JOBS表からは結合条件に合致しないデータも取り出さなくてななりません。
したがって、「... jobs j LEFT OUTER JOIN ...」か「... RIGHT OUTER JOIN jobs j ...」のように外部結合しているものが正解です。

以上より、
・SELECT e.employee_name, j.job_name FROM employees e RIGHT OUTER JOIN jobs j ON e.job_id = j.job_id;
が正解となります。

正解のSQL文の実行結果は次のようになります。



その他の選択肢については次のとおりです。

・SELECT e.employee_name, j.job_name FROM employees e LEFT OUTER JOIN jobs j ON e.job_id = j.job_id;
・SELECT e.employee_name, j.job_name FROM jobs j RIGHT OUTER JOIN employees e ON e.job_id = j.job_id;
どちらのSQL文も、結合条件を満たしていない(職種の無い)従業員表のデータも含めて表示されます。(但しサンプルデータ上は、そのような従業員は存在しません。)

・SELECT e.employee_name, j.job_name FROM employees e FULL OUTER JOIN jobs j ON e.job_id = j.job_id;
完全外部結合です。EMPLOYEES表、JOBS表の2つの表の結合条件を満たしていないデータも含めて表示されます。

参考

結合条件を満たしたデータのみを取り出すのではなく、結合条件を満たしていないデータも一緒に取り出す方法を外部結合といいます(結合条件を満たすデータのみを取り出す方法を内部結合といいます)。

外部結合には、次の3つの方法があります。



 SELECT [表接頭辞.]列名 [, [表接頭辞.]列名 ...]
 FROM 表名1
  {LEFT | RIGHT | FULL} [OUTER] JOIN 表名2
  ON 結合条件 ;

左側外部結合は結合条件を満たすデータと、JOIN句の左側に指定された表のデータを全て取り出す結合です。


 

SQLを表示
SELECT emp.employee_name, mgr.employee_name
FROM employees emp LEFT OUTER JOIN employees mgr
 ON emp.manager_id = mgr.employee_id;


右側外部結合は結合条件を満たすデータと、JOIN句の右側に指定された表のデータを全て取り出す結合です。


 
SQLを表示
SELECT e.employee_name, j.job_name
FROM employees e RIGHT OUTER JOIN jobs j
 ON e.job_id = j.job_id;


完全外部結合はJOIN句の左右に指定された表のデータを条件を満たしていないデータも含めて全て取り出す結合です。


 
SQLを表示
SELECT emp.employee_name, mgr.employee_name
FROM employees emp FULL OUTER JOIN employees mgr
 ON emp.manager_id = mgr.employee_id;


また、Oracle独自の結合構文で外部結合を行えます。その際は外部結合演算子(+)を使用します。
Oracle独自の外部結合構文は次のとおりです。

 SELECT [表接頭辞.]列名 [, [表接頭辞.]列名 ...]
 FROM 表名1, 表名2
 WHERE [表接頭辞1.]列名[(+)] = [表接頭辞2.]列名[(+)]
 [AND 結合条件以外の条件];

Oracle独自の結合構文での外部結合では、WHERE句に指定した条件の左側に(+)をつけると右側外部結合、右側につけると左側外部結合の結果と等しくなります。


 
SQLを表示
SELECT p.category, p.name, o.name
FROM prod p, oldprod o
WHERE p.category(+) = o.category;

SELECT p.category, p.name, o.name
FROM prod p RIGHT OUTER JOIN oldprod o
 ON p.category = o.category;



 
SQLを表示
SELECT p.category, p.name, o.name
FROM prod p, oldprod o
WHERE p.category = o.category(+);

SELECT p.category, p.name, o.name
FROM prod p LEFT OUTER JOIN oldprod o
 ON p.category = o.category;


なお、Oracle独自の結合構文での外部結合では、完全外部結合は行えません。WHERE句の条件の両方に(+)をつけるとエラーとなります。
完全外部結合には FULL [OUTER] JOINを使用します。


 
SQLを表示
SELECT p.category, p.name, o.name
FROM prod p, oldprod o
WHERE p.category(+) = o.category(+);

SELECT p.category, p.name, o.name
FROM prod p FULL OUTER JOIN oldprod o
 ON p.category = o.category;

上に戻る

FULL OUTER JOIN の結合条件

公開日 2024/02/20

上記問題にて、下記の表記がありました。
・SELECT e.employee_name, j.job_name FROM employees e FULL OUTER JOIN jobs j ON e.job_id = j.job_id;
完全外部結合です。EMPLOYEES表、JOBS表の2つの表の結合条件を満たしていないデータも含めて表示されます。

問題文には、「担当する従業員がいない職種も含めて職種情報を表示するものとします。」とありますので、FULL OUTER JOINを使用しても条件は満たされていると考えられます。
結合条件を満たしていない(職種のない)従業員のデータも含めるべきかどうかは明記されていないため、このクエリは条件を満たしていると思います。

スタッフからの返信

s staff_ishii

2024/02/21 17:32

sekakuma3 さん ご指摘の点を修正いたしました。 ご報告、誠にありがとうございました。

この投稿に対して返信しませんか?