助け合いフォーラム

Oracle DB

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



給与の額が所属する部署の最低給与を超える従業員の一覧と、部署ごとの最低給与を表示します。
以下の問合せを実行しましたが、実行結果について正しい記述はどれですか。

 SELECT e.employee_name, e.salary, e.department_id, s.minsal
 FROM employees e, (SELECT department_id, MIN(salary) minsal FROM employees GROUP BY department_id) s
 WHERE e.salary > s.minsal
 ORDER BY e.department_id, e.salary;

正解

実行されるが正しい結果が返されない

解説

設問のSQL文は、Oracle独自の結合構文です。

Oracle独自の結合構文では、
・結合する表名は,(カンマ)で区切ってFROM句に指定
・結合条件はWHERE句に指定
・結合条件以外の条件はWHERE句に指定した結合条件の後にAND演算子で指定
します。

設問のSQL文ではEMPLOYEES表と、部署ごとの最低給与を問合せる( )で囲まれた副問合せをFROM句に指定し、両者を結合しています。
しかし、WHERE句には「e.salary > s.minsal」という検索条件しか指定されておらず、結合条件が欠けています。この場合エラーとはなりませんが、結合した全てのデータの組み合わせが返ってくるので正しい結果は得られません。

以上より、
・実行されるが正しい結果が返されない
が正解となります。

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


SQLを表示
SELECT e.employee_name, e.salary, e.department_id, s.minsal
FROM employees e, (SELECT department_id, MIN(salary) minsal FROM employees GROUP BY department_id) s
WHERE e.salary > s.minsal
ORDER BY e.department_id, e.salary;


正しく実行するには、WHERE句に結合条件を指定します。


SQLを表示
SELECT e.employee_name, e.salary, e.department_id, s.minsal
FROM employees e, (SELECT department_id, MIN(salary) minsal FROM employees GROUP BY department_id) s
WHERE e.department_id = s.department_id
AND e.salary > s.minsal
ORDER BY e.department_id, e.salary;

参考

Oracle Databaseには、Oracle独自の結合構文があります。
構文は以下の通りです。

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

 
 
SQLを表示
SELECT d.department_id, d.department_name, e.employee_id,e.employee_name
FROM departments d, employees e
WHERE d.department_id = e.department_id
 AND salary BETWEEN 200000 AND 450000;


Oracle独自の結合構文では、
・結合する表名は,(カンマ)で区切ってFROM句に指定
・結合条件はWHERE句に指定
・結合条件以外の条件はWHERE句に指定した結合条件の後にAND演算子で指定
します。

ON句を使用した結合同様に、結合する2つの表にある同じ名前の列をSELECT句やWHERE句に指定する場合は、必ず表接頭辞を使用して列を指定しなければなりません。


 
SQLを表示
SELECT department_id, d.department_name, e.employee_id,e.employee_name
FROM departments d, employees e
WHERE d.department_id = e.department_id
 AND salary BETWEEN 200000 AND 450000;


なお、以下はOracle Databaseで使用できる表の結合方法(ANSI SQL:1999準拠の結合構文)で、〇がついているものはOracle独自の結合構文でも記述できます。


SQL:1999準拠の結合構文とOracle独自の結合構文とではパフォーマンスに違いはありません。
上に戻る

WHERE句で列別名を使用

投稿日 2023/01/02

列別名を使用できるのはORDER BY句のみという認識なのですが、なぜエラーにならないのでしょうか?
例外などありましたでしょうか。調べてもわからなかったのでどなたか教えてください。

2023/01/04 13:38

FROM句に副問合せがあるからのようです。
問題ID:26896の解説に以下のように書いてありました。

SQL文は以下の順序で評価されるため、通常は列別名だけを指定できるのはORDER BY句のみです(SELECT句で指定した列別名を認識できるのはORDER BY句のみのため)。

(評価順) FROM句→WHERE句→GROUP BY句→HAVING句→SELECT句→ORDER BY句

ですが、設問のSQL文ではFROM句の副問合せ(インライン・ビュー)で算術式に列別名を指定しているため、FROM句の後に評価される全ての句で列別名が認識されます。


コメント

m mmmss125

2023/01/08 16:59

そんな決まりがあったのですね。。 ありがとうございます。

この返信に対して
コメントを記入できます

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