助け合いフォーラム
Oracle Master Silver SQL 2019(1Z0-071)
問題ID : 26507
問題を開く
EMPLOYEES表の構造を確認して下さい。

EMPLOYEES表のMANAGER_ID列には上司のEMPLOYEE_IDが登録されています。また、上司のいない従業員のMANAGER_ID列にはNULL値が登録されています。
従業員名とその上司の氏名を表示するには、どの問い合わせを実行しますか。
ただし、上司がいない従業員については、上司の氏名欄を空欄として表示して下さい。

EMPLOYEES表のMANAGER_ID列には上司のEMPLOYEE_IDが登録されています。また、上司のいない従業員のMANAGER_ID列にはNULL値が登録されています。
従業員名とその上司の氏名を表示するには、どの問い合わせを実行しますか。
ただし、上司がいない従業員については、上司の氏名欄を空欄として表示して下さい。
正解
SELECT emp.employee_name, mgr.employee_name FROM employees emp LEFT OUTER JOIN employees mgr ON emp.manager_id = mgr.employee_id;
解説
従業員の氏名はEMPLOYEES表から取り出せます。
しかし上司の氏名を取り出すには、EMPLOYEES表のMANAGER_ID列の値でEMPLOYEES表を検索し、EMPLOYEE_NAME列の値を取り出す必要があります。
このようなデータの取り出しを行うには、従業員の氏名を持つEMPLOYEES表と、MANAGER_IDを持つEMPLOYEES表があると見立てて、2つの表を結合します(自己結合といいます)。
また、設問の「上司がいない従業員については、上司の氏名欄を空欄として下さい」より、上司のいない従業員のデータも取り出すということがわかります。これは結合条件に合致しないデータも取り出すということですので、外部結合を行います。
全ての選択肢において表別名empから従業員名を、mgrから上司名を取り出していますが、empから取り出す従業員名は結合条件に合致しないデータも取り出さなくてはなりません。
全ての選択肢において、列別名empはJOIN句の左側にありますので、LEFT OUTER JOINを使用します。
以上より、
・SELECT emp.employee_name, mgr.employee_name FROM employees emp LEFT OUTER JOIN employees mgr ON emp.manager_id = mgr.employee_id;
が正解となります。
正解のSQL文の実行結果は次のようになります。

その他の選択肢については次のとおりです。
・SELECT emp.employee_name, mgr.employee_name FROM employees emp JOIN employees mgr ON emp.manager_id = mgr.employee_id;
この結合では上司のいない従業員(MANAGER_ID列の値がNULL)が表示されません。
・SELECT emp.employee_name, mgr.employee_name FROM employees emp RIGHT OUTER JOIN employees mgr ON emp.manager_id = mgr.employee_id;
この結合では部下がいない場合でも上司名を全て取り出します。上司がいない従業員は表示されません。
・SELECT emp.employee_name, mgr.employee_name FROM employees emp FULL OUTER JOIN employees mgr ON emp.manager_id = mgr.employee_id;
完全外部結合です。2つの表の結合条件を満たしていないデータも含めて表示されます。
しかし上司の氏名を取り出すには、EMPLOYEES表のMANAGER_ID列の値でEMPLOYEES表を検索し、EMPLOYEE_NAME列の値を取り出す必要があります。
このようなデータの取り出しを行うには、従業員の氏名を持つEMPLOYEES表と、MANAGER_IDを持つEMPLOYEES表があると見立てて、2つの表を結合します(自己結合といいます)。
また、設問の「上司がいない従業員については、上司の氏名欄を空欄として下さい」より、上司のいない従業員のデータも取り出すということがわかります。これは結合条件に合致しないデータも取り出すということですので、外部結合を行います。
全ての選択肢において表別名empから従業員名を、mgrから上司名を取り出していますが、empから取り出す従業員名は結合条件に合致しないデータも取り出さなくてはなりません。
全ての選択肢において、列別名empはJOIN句の左側にありますので、LEFT OUTER JOINを使用します。
以上より、
・SELECT emp.employee_name, mgr.employee_name FROM employees emp LEFT OUTER JOIN employees mgr ON emp.manager_id = mgr.employee_id;
が正解となります。
正解のSQL文の実行結果は次のようになります。

その他の選択肢については次のとおりです。
・SELECT emp.employee_name, mgr.employee_name FROM employees emp JOIN employees mgr ON emp.manager_id = mgr.employee_id;
この結合では上司のいない従業員(MANAGER_ID列の値がNULL)が表示されません。
・SELECT emp.employee_name, mgr.employee_name FROM employees emp RIGHT OUTER JOIN employees mgr ON emp.manager_id = mgr.employee_id;
この結合では部下がいない場合でも上司名を全て取り出します。上司がいない従業員は表示されません。
・SELECT emp.employee_name, mgr.employee_name FROM employees emp FULL OUTER JOIN employees mgr ON emp.manager_id = mgr.employee_id;
完全外部結合です。2つの表の結合条件を満たしていないデータも含めて表示されます。
参考
結合条件を満たしたデータのみを取り出すのではなく、結合条件を満たしていないデータも一緒に取り出す方法を外部結合といいます(結合条件を満たすデータのみを取り出す方法を内部結合といいます)。
外部結合には、次の3つの方法があります。

SELECT [表接頭辞.]列名 [, [表接頭辞.]列名 ...]
FROM 表名1
{LEFT | RIGHT | FULL} [OUTER] JOIN 表名2
ON 結合条件 ;
左側外部結合は結合条件を満たすデータと、JOIN句の左側に指定された表のデータを全て取り出す結合です。

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

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

また、Oracle独自の結合構文で外部結合を行えます。その際は外部結合演算子(+)を使用します。
Oracle独自の外部結合構文は次のとおりです。
SELECT [表接頭辞.]列名 [, [表接頭辞.]列名 ...]
FROM 表名1, 表名2
WHERE [表接頭辞1.]列名[(+)] = [表接頭辞2.]列名[(+)]
[AND 結合条件以外の条件];
Oracle独自の結合構文での外部結合では、WHERE句に指定した条件の左側に(+)をつけると右側外部結合、右側につけると左側外部結合の結果と等しくなります。


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

外部結合には、次の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;
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;
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;
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;
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;
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;
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;
スペルミス
投稿日 2026/02/15
(MANAGET_ID列の値がNULL)が表示されません。
→スペルミス(正:MANAGER_ID)
スタッフからの返信
この投稿に対して返信しませんか?
s staff_ishii
2026/02/17 23:46
usagi_wfr さん、 ご指摘の点を修正いたしました。 ご報告、誠にありがとうございました。