助け合いフォーラム
従業員名とその上司の氏名を表示するには、どの問い合わせを実行しますか(該当するものを全て選択して下さい)。
正解
SELECT emp.employee_name, mgr.employee_name FROM employees emp, employees mgr WHERE emp.manager_id = mgr.employee_id;
SELECT emp.employee_name, mgr.employee_name FROM employees emp JOIN employees mgr ON emp.manager_id = mgr.employee_id;
解説
しかし上司の氏名を取り出すには、EMPLOYEES表のMANAGER_ID列の値でEMPLOYEES表を検索し、EMPLOYEE_NAME列の値を取り出す必要があります。
このようなデータの取り出しを行うには、従業員の氏名を持つEMPLOYEES表と、MANAGER_IDを持つEMPLOYEES表があると見立てて、2つの表を結合します(自己結合といいます)。
自己結合はON句もしくはOracle独自の結合構文で行えます。
以上より、
・SELECT emp.employee_name, mgr.employee_name FROM employees emp, employees mgr WHERE emp.manager_id = mgr.employee_id;
・SELECT emp.employee_name, mgr.employee_name FROM employees emp JOIN employees mgr ON emp.manager_id = mgr.employee_id;
が正解となります。
正解のSQL文の実行結果は次のようになります。
FROM employees emp, employees mgr
WHERE emp.manager_id = mgr.employee_id;
FROM employees emp JOIN employees mgr
ON emp.manager_id = mgr.employee_id;
その他の選択肢については次のとおりです。
・SELECT emp.employee_name, mgr.employee_name FROM employees emp NATURAL JOIN employees mgr;
結合列に表接頭辞を使用しているため、エラーとなります。
・SELECT emp.employee_name, mgr.employee_name FROM employees emp JOIN employees mgr USING (employee_id);
従業員名とその上司の氏名を表示するには、EMPLOYEE_ID列とMANAGER_ID列で結合しなければなりません。
・SELECT employee_name, mgr.employee_name FROM employees JOIN employees mgr ON manager_id = mgr.employee_id;
自己結合を行う場合は、表に対して必ず表別名を指定します。
参考
自己結合を行うには、次のように記述します。
SELECT 表別名.列名 [,表別名.列名 ...]
FROM 表名1 表別名1 JOIN 表名1 表別名2
ON 表別名1.列名 = 表別名2.列名 ;
自己結合を行う場合は、表に対して必ず表別名を指定します。
FROM employees emp JOIN employees mgr
ON emp.manager_id = mgr.employee_id;
また、Oracle独自の結合構文で自己結合を行うには、次のように記述します。
SELECT 表別名.列名 [,表別名.列名 ...]
FROM 表名1 表別名1, 表名1 表別名2
WHERE 表別名1.列名 = 表別名2.列名 ;
FROM employees emp, employees mgr
WHERE emp.manager_id = mgr.employee_id;
Employeesテーブルのデータについて
配布されている検証用データのEmployees表のデータを確認したところ、manager_idの列のデータがnullの行とそうでない行がありました。
これは、上司の人はmanager_idを持たず、上司のいる従業員のmanager_id列に上司のemployee_idが入るという認識で合ってますでしょうか。
また、本問題は表の構造だけ見て解けるものなのでしょうか
表データも見ないとわからない気がするのですが…
これは、上司の人はmanager_idを持たず、上司のいる従業員のmanager_id列に上司のemployee_idが入るという認識で合ってますでしょうか。
そうですね。その理解で良いと思います。
前提として「manager_id列に値が入っているレコードは、上司がいることを意味する」と判断しておく必要はありますが、実際の表データは見なくても問題は解けるかなと思います。
以下の2つの選択肢は構文エラーになるので除外。
・SELECT emp.employee_name, mgr.employee_name FROM employees emp NATURAL JOIN employees mgr;
・SELECT employee_name, mgr.employee_name FROM employees JOIN employees mgr ON manager_id = mgr.employee_id;
以下の選択肢は、同じ名前が表示されるだけなので、期待する結果(従業員名とその上司の氏名)にはならないと判断できる。
・SELECT emp.employee_name, mgr.employee_name FROM employees emp JOIN employees mgr USING (employee_id);
そして残りの2つについては、manager_id列に値を持つemployee_nameと、そのmanger_idに該当するemployee_nameが表示されるので、本設問で期待されている「従業員名とその上司の氏名」(と思われるもの)が表示されるので正答である、と判断はできないことはないかなと思いました。
・SELECT emp.employee_name, mgr.employee_name FROM employees emp, employees mgr WHERE emp.manager_id = mgr.employee_id;
・SELECT emp.employee_name, mgr.employee_name FROM employees emp JOIN employees mgr ON emp.manager_id = mgr.employee_id;
もし、運営さんに修正してもらうとしたら、「manager_id列に値が入ってるレコードは、その従業員に上司がいることを意味する」のような補足を問題文に追記してもらうぐらいでしょうか。
実際のSilver SQL 2019の試験問題で、どのような出題がされるかはなんとも言えないところですが...。
コメント
この投稿に対して返信しませんか?
k kyomukyomu
2024/02/13 17:16
ご回答いただきありがとうございます。 確かに消去法で解けないことはないですね。 ご親切にありがとうございました。