助け合いフォーラム
次のSQLと同じ結果となるSQL文はどれですか(該当するものを全て選択して下さい)。
SELECT department_id, department_name, employee_name, hiredate
FROM departments NATURAL JOIN employees
ORDER BY department_id, employee_id, hiredate;
正解
SELECT department_id, d.department_name, e.employee_name, e.hiredate FROM departments d JOIN employees e USING(department_id, manager_id) ORDER BY department_id, e.employee_id, e.hiredate;
SELECT d.department_id, d.department_name, e.employee_name, e.hiredate FROM departments d JOIN employees e ON d.department_id = e.department_id AND d.manager_id = e.manager_id ORDER BY department_id, employee_id, hiredate;
解説
設問のDEPARTMENTS表とEMPLOYEES表では、同名で同じデータ型の列はDEPARTMENT_ID列とMANAGER_ID列になりますので、設問のSQL文の結果は、これらの2つの列が等しいという結合条件で2つの表を結合した結果と等しくなります。
2つの表の特定の列の値が等しいデータを結合することを等価結合といいますが、等価結合を行うには自然結合のほか、USING句による結合とON句による結合、Oracle独自の結合構文による結合があります。
設問の選択肢では、USING句による結合とON句による結合があります。
USING句による結合では、2つの表に共通するある同名の列で、結合に使用する列をUSING句に指定すればよいので、USING句にDEPARTMENT_ID列とMANAGER_ID列を指定します。
また、ON句による結合では、結合条件をON句に指定しますので、ON句にDEPARTMENTS表.DEPARTMENT_ID = EMPLOYEES表.DEPARTMENT_IDとDEPARTMENTS表.MANAGER_ID = EMPLOYEES表.MANAGER_IDを指定します。
以上より、
・SELECT department_id, d.department_name, e.employee_name, e.hiredate FROM departments d JOIN employees e USING(department_id, manager_id) ORDER BY department_id, e.employee_id, e.hiredate;
・SELECT d.department_id, d.department_name, e.employee_name, e.hiredate FROM departments d JOIN employees e ON d.department_id = e.department_id AND d.manager_id = e.manager_id ORDER BY department_id, employee_id, hiredate;
が正解となります。
設問と正解のSQL文の実行結果は次のようになります。
FROM departments NATURAL JOIN employees
ORDER BY department_id, employee_id, hiredate;
FROM departments d JOIN employees e
USING(department_id, manager_id)
ORDER BY department_id, e.employee_id, e.hiredate;
FROM departments d JOIN employees e
ON d.department_id = e.department_id
AND d.manager_id = e.manager_id
ORDER BY department_id, employee_id, hiredate;
その他の選択肢については次のとおりです。
・SELECT d.department_id, d.department_name, e.employee_name, e.hiredate FROM departments d JOIN employees e USING(department_id, manager_id) ORDER BY d.department_id, e.employee_id,e. hiredate;
USING句を指定した結合では、結合列に表接頭辞を使用することはできません。SELECT句やORDER BY句に指定されたDEPARTMENT_ID列に表接頭辞が指定されているためエラーとなります。
・SELECT d.department_id, d.department_name, e.employee_name, e.hiredate FROM departments d JOIN employees e ORDER BY department_id, employee_id, hiredate;
NATURAL JOIN句では結合する列が自動的に判断されるため結合条件の記述は必要ありませんが、JOIN句の場合はUSING句やON句で結合条件を記述する必要があります。
・SELECT department_id, d.department_name, e.employee_name, e.hiredate FROM departments d JOIN employees e USING(department_id) ORDER BY department_id, e.employee_id, e.hiredate;
結合条件にDEPARTMENT_ID列しか指定されていないため、エラーとはなりませんが、設問のSQL文とは実行結果が異なります。
参考
等価結合を行うには次の方法があります。
・自然結合(NATURAL JOIN)
・USING句を使用した結合
・ON句を使用した結合
・Oracle独自の結合構文による結合
order byの表接頭辞
正解選択肢のjoinでの結合ですが、order byのdepartment_idに表接頭辞がついていない
エラーにならないか?
ORDER BY department_id
問題の以下の解説にも記載されているように、結合列に表接頭辞を使用することはできないので、正答とされているクエリで正しいと思います。
USING句を指定した結合では、結合列に表接頭辞を使用することはできません。SELECT句やORDER BY句に指定されたDEPARTMENT_ID列に表接頭辞が指定されているためエラーとなります。
Ping-tさんのこちらの問題集には検証環境準備用のスクリプトが提供されているので、そちらを利用して正答のクエリを実際に実行してみましたがエラーは発生しませんでした。
参考:
https://docs.oracle.com/cd/F19136_01/sqlrf/SELECT.html#GUID-CFA006CA-6FF1-4972-821E-6996142A51C6
コメント
この投稿に対して返信しませんか?
y yuyuuutata
2023/05/26 11:07
解答ありがとうございます。 知りたかったのはusingでの結合ではなく、joinの場合です。 いずれにしても、検証用でエラーは発生しないと理解しました。。。