助け合いフォーラム

Oracle DB

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



以下のSQL文を実行した結果について、正しい記述はどれですか。

 SELECT department_id, maxincome, minincome
 FROM (SELECT department_id, MAX(commission + (salary * 12)) maxincome,
    MIN(commission + (salary * 12)) minincome FROM employees GROUP BY department_id)
 WHERE minincome > maxincome / 2
 ORDER BY department_id;

正解

部署の最低年収が最高年収の半分より多い部署の情報が表示される

解説

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

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

ですが、設問のSQL文ではFROM句の副問合せ(インライン・ビュー)で算術式に列別名を指定しているため、FROM句の後に評価される全ての句で列別名が認識されます。
FROM句の副問合せでは、部署ごとの年収(commission + (salary * 12))の最高額と最低額にそれぞれmaxincome、minincomeと列別名を指定し、その後のWHERE句→SELECT句でも簡潔な列別名で問合せが実行されます。GROUP BY句やHAVING句が含まれていたとしても、同様に列別名は認識されます。
FROM句で部署ごとの最高年収、最低年収を取り出し、WHERE句で最高年収の半分より多い最低年収という条件に絞っています。

以上より、
・部署の最低年収が最高年収の半分より多い部署の情報が表示される
が正解となります。

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


SQLを表示
SELECT department_id, maxincome, minincome
FROM (SELECT department_id, MAX(commission + (salary * 12)) maxincome,
MIN(commission + (salary * 12)) minincome FROM employees GROUP BY department_id)
WHERE minincome > maxincome / 2
ORDER BY department_id;


その他の選択肢については次のとおりです。

・SELECT句に列別名だけを指定できないので、エラーとなる
・WHERE句に列別名を指定できないので、エラーとなる
FROM句の副問合せで列別名を指定した場合、FROM句の後に実行される全ての句で列別名が認識されるので、問合せは正常に実行されます。

・FROM句の副問合せでエラーとなる
FROM句で副問合せを使用でき、インライン・ビューとも呼ばれます。

参考

Oracle DatabaseではSQL文の中に別のSQL文を入れ子にして実行することができ、入れ子の内側の問合せのことを副問合せといいます(副問合せに対し、外側の問合せを主問合せといいます)。
副問合せは次のように記述します。

 SELECT 列名[, 列名 ...]
 FROM 表名
 WHERE 列名 比較演算子 (SELECT 列名 FROM 表名 [WHERE 条件]);

副問合せの部分は()括弧で囲みます。(INSERT文で副問合せを使用してデータの追加を行う場合は、()は必須ではありません。分野「DML文」のINSERT文の参考をご参照ください。)
上記では比較演算子の右辺に副問合せを記述していますが、副問合せを左辺に定義してもかまいません。

通常の副問合せを使用したSQL文ではまず副問合せが実行され、副問合せの実行結果をもとに主問合せが実行されます。


 
SQLを表示
SELECT employee_name, salary
FROM employees
WHERE salary > (SELECT AVG(NVL(salary, 0)) FROM employees);


副問合せからNULL値が戻された場合、主問合せの実行結果は0件となります(エラーとはなりません)。
次のような場合に、副問合せは主問合せにNULL値を返します。

[副問合せの結果、データが1件も取り出されない場合]

 
SQLを表示
SELECT * FROM employees WHERE employee_id = 1;

SELECT employee_name, hiredate, salary
FROM employees
WHERE salary >
 (SELECT salary FROM employees WHERE employee_id = 1);


[副問合せの結果がNULL値である場合]

 
SQLを表示
SELECT employee_id FROM employees
WHERE salary IS NULL;

SELECT employee_name, hiredate, salary
FROM employees
WHERE salary >
 (SELECT salary FROM employees
 WHERE employee_id = 1017);


副問合せには、次のようにいろいろな使用方法があります。
・SELECT文のSELECT句、FROM句、WHERE句、HAVING句、ORDER BY句や、INSERT文、UPDATE文等のDML文で使用できる
・主問合せと副問合せで異なる表にアクセスできる
・1つの主問合せに対し、複数の副問合せを指定できる
・副問合せをネストできる(WHERE句に指定した副問合せでは255レベルのネストが可能)
・副問合せの中でGROUP BY句やHAVIMG句、ORDER BY句を使用できる

なお、副問合せは主問合せに戻すデータの件数により、単一行副問合せと複数行副問合せに分類されます。


※複数行副問合せは結果として1件のデータを戻す場合もあります。

副問合せがWHERE句などに指定する条件の一部として使用される場合、単一行副問合せでは単一行演算子を、複数行副問合せでは複数行演算子を使用して条件の判定を行います。



[単一行副問合せ]

 
SQLを表示
SELECT AVG(salary) FROM employees;

SELECT employee_name, hiredate, salary
FROM employees
WHERE salary >
 (SELECT AVG(salary) FROM employees);


[複数行副問合せ]

SQLを表示
SELECT MIN(salary) FROM employees
GROUP BY department_id;

SELECT employee_name, hiredate, salary
FROM employees
WHERE salary =ANY
 (SELECT MIN(salary) FROM employees
 GROUP BY department_id);


なお、単一行副問合せの場合、比較演算子に複数行演算子を使用してもエラーにならず正常に実行されます。しかし、複数行副問合せに単一行演算子を使用するとエラーとなります。


 
SQLを表示
SELECT AVG(salary) FROM employees;

SELECT employee_name, hiredate, salary
FROM employees
WHERE salary >ANY
 (SELECT AVG(salary) FROM employees);



 
SQLを表示
SELECT AVG(salary) FROM employees
GROUP BY department_id;

SELECT employee_name, hiredate, salary
FROM employees
WHERE salary >
 (SELECT AVG(salary) FROM employees
 GROUP BY department_id);


また、副問合せでは複数の列を返し、その値の組合せで比較する事もできます。複数の列を返す副問合せを、複数列副問合せといいます。
複数列副問合せは、単一行副問合せ、複数行副問合せのどちらとも組合せて使用できます。


 
SQLを表示
SELECT employee_id, employee_name
FROM employees
WHERE (department_id, employee_id) IN
 (SELECT department_id, manager_id
 FROM departments);
上に戻る

表別名が必要なのでは...

投稿日 2025/12/15

インラインビューで表別名がないケースを見たことがないのですが表別名をつけることを推奨しているだけで動作としては問題ないのでしょうか?

2025/12/17 21:09

この設問においては、問題文のように別名なしでも結果は同じになると思いますが、実務上は特に可読性の観点からも必ず別名つけますよね(JOINするような場合ならもちろん)。
手持ちの試験対策系テキストを少し見て見ましたが、インラインビューの解説の中で別名を使っていないSQLも掲載されているようでした。FROM句に指定する副問合せの説明としては問題なさそうです。


コメント

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

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