助け合いフォーラム



全従業員の従業員名、所属部署名、職種名を表示するには、どの問い合わせを実行しますか(該当するものを全て選択して下さい)。
ただし、上司のいない従業員に関してはEMPLOYEES表のMANAGER_ID列にNULL値が登録されています。
正解
SELECT employee_name, department_name, job_name FROM departments d JOIN employees e ON d.department_id = e.department_id JOIN jobs j ON e.job_id = j.job_id;
SELECT employee_name, department_name, job_name FROM departments JOIN employees USING (department_id) JOIN jobs USING (job_id);
SELECT employee_name, department_name, job_name FROM employees NATURAL JOIN jobs JOIN departments USING (department_id);
解説
3つ以上の表を結合する場合は、
表名1 JOIN 表名2 ON 結合条件
JOIN 表名3 ON 結合条件
...
のように記述しますが、表Aは自然結合で結合する、表BはUSINGを使用した結合で結合するなどのように、結合方法を混在することもできます。
設問では、DEPARTMENTS表とEMPLOYEES表ではDEPARTMENT_ID列を、EMPLOYEES表とJOBS表ではJOB_ID列を結合列として表を結合します。
DEPARTMENTS表とEMPLOYEES表では、MANAGER_ID列も2つの表において同名の列ですが、MANAGER_ID列を結合列に加えてしまうと、DEPARTMENT_ID列とMANAGER_ID列の組合せで結合されるため、MANAGER_IDがNULL値である列は結合されず、全従業員のデータを取り出すことができなくなってしまうので注意が必要です。
以上より、
・SELECT employee_name, department_name, job_name FROM departments d JOIN employees e ON d.department_id = e.department_id JOIN jobs j ON e.job_id = j.job_id;
・SELECT employee_name, department_name, job_name FROM departments JOIN employees USING (department_id) JOIN jobs USING (job_id);
・SELECT employee_name, department_name, job_name FROM employees NATURAL JOIN jobs JOIN departments USING (department_id);
が正解となります。
正解のSQL文の実行結果は次のようになります。
FROM departments d JOIN employees e
ON d.department_id = e.department_id JOIN jobs j
ON e.job_id = j.job_id;

FROM departments
JOIN employees USING (department_id)
JOIN jobs USING (job_id);

FROM employees NATURAL JOIN jobs
JOIN departments USING (department_id);
その他の選択肢については次のとおりです。
・SELECT employee_name, department_name, job_name FROM departments NATURAL JOIN employees JOIN jobs USING (job_id);
DEPARTMENTS表とEMPLOYEES表にはDEPARTMENT_ID列とMANAGER_ID列の2つの同名の列があります。自然結合ではこの2つの列が結合列として使用されますが、MANAGER_IDがNULL値である列は結合されませんので、エラーとはなりませんが、全従業員のデータを取り出すことはできません。

・SELECT employee_name, department_name, job_name FROM departments d JOIN employees e JOIN jobs j ON d.department_id = e.department_id ON e.job_id = j.job_id;
このSQLは構文が誤っている為、エラーになります。
複数の表を結合する場合は、
表名1 JOIN 表名2 ON 結合条件
JOIN 表名3 ON 結合条件
...
のように記述します。

参考
表の結合では、3つ以上の表を結合することもできます。
3つ以上の表を結合する場合、Oracle Databaseは結合順序を自動的に決定します。そして、最初に結合する2つの表を選択し、その結合結果と残りの表の中から選択した表を結合する、という処理を繰り返します。
ON句を使用して3つ以上の表を結合するには、次のように記述します。
SELECT [表接頭辞.]列名 [, [表接頭辞.]列名 ...]
FROM 表名1
JOIN 表名2 ON 結合条件
JOIN 表名3 ON 結合条件
JOIN ...
[WHERE 結合条件以外の条件];
FROM departments d JOIN employees e
ON d.department_id = e.department_id JOIN jobs j
ON e.job_id = j.job_id;
3つ以上の表の結合は、自然結合やUSING句を使用した結合でも行うことができます。

FROM departments
JOIN employees USING (department_id)
JOIN jobs USING (job_id);

FROM employees
NATURAL JOIN departments
NATURAL JOIN jobs;
なお、NATURAL JOIN句とUSING句を1つの結合で同時に指定することはできませんが、3つ以上の表の結合において、表Aは自然結合で結合する、表BはUSINGを使用して結合するなどのように、結合方法を混在することができます。

FROM employees NATURAL JOIN jobs
JOIN departments USING (department_id);
なぜ、SELECT句に表接頭辞がついていない列名が指定されているのにエラーにならないのでしょうか。
タイトルの通りです。もし、わかる方いたらお願いします。
SELECT employee_name, department_name, job_name
FROM departments d JOIN employees e
ON d.department_id = e.department_id JOIN jobs j
ON e.job_id = j.job_id;
ID:26499の参考に次の説明があります。
ON句を使用した結合では、結合する2つの表にある同じ名前の列をSELECT句やWHERE句に指定する場合は、必ず表接頭辞を使用して列を指定しなければなりません。
「結合する2つの表にある同じ名前の列をSELECT句やWHERE句に指定する場合は、必ず表接頭辞を使用する」なので、
逆に言えば、結合する表にある同じ名前の列をSELECT句やWHERE句に指定しない場合は、接頭辞は省略できます。
上記SQL文のSELECT句のemployee_name, department_name, job_nameはそれぞれの表にしか存在せず、複数の表で同じ名前の列はありませんね。
コメント
この投稿に対して返信しませんか?
M Mottchan
2023/01/27 14:19
2つ以上の表の中で、ユニークな列名であれば表接頭辞はいらないんですね。 大変参考になります。ありがとうございます。