助け合いフォーラム

Oracle DB

Oracle Master Silver SQL 2019(1Z0-071)
問題ID : 26713
問題を開く
副問合せが使用できる句はどれですか(該当するものを全て選択して下さい)。

正解

SELECT句

FROM句

WHERE句

HAVING句

ORDER BY句

解説

副問合せは、SELECT文のSELECT句、FROM句、WHERE句、HAVING句、ORDER BY句の他、INSERT文やUPDATE文等のDML文でも使用することができます。

以上より、
・SELECT句
・FROM句
・WHERE句
・HAVING句
・ORDER BY句
が正解となります。

以下にSELECT文のそれぞれの句で副問合せを使用した例を紹介します。

[SELECT句]

 
SQLを表示
SELECT employee_name,
 (SELECT department_name FROM departments
 WHERE department_id = 1) dept_name,
 salary
FROM employees
WHERE department_id = 1;


[FROM句]
※FROM句の副問合せはインライン・ビューとも呼ばれます

 
SQLを表示
SELECT emp.*
FROM (SELECT employee_name, hiredate, salary
  FROM employees
  WHERE department_id = 5) emp;


[WHERE句]

 
SQLを表示
SELECT employee_name, salary
FROM employees
WHERE salary = (SELECT MAX(salary) FROM employees);


[HAVING句]

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


[ORDER BY句]
※副問合せの中でそのFROM句に無い表を参照する場合(副問合せの外側にある表を参照する場合)、相関副問合せと呼ばれます。

 
SQLを表示
SELECT department_id FROM employees e
ORDER BY
(SELECT department_name FROM departments d
 WHERE d.department_id = e.department_id);

参考

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句を使用できる

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



副問合せが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);
上に戻る

副問い合わせっでGROUP BY句が使えない?

投稿日 2024/10/21

本問の参考にて、

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

とあるので、副問い合わせでもGROUP BYは使える整理なんですが
なぜ正解でGROUP BY句が使えないとあるのでしょうか?

2024/10/22 02:09

問題文を読み間違えているかと思われます。
副問い合わせの中でGROUP BYは使えますが、
本問はGROUP BY句の中で副問合せが使用できるか否かを問われています。

質問者様の「副問い合わせでもGROUP BYは使える」の意図は下記のものかと思われます。
こちらはFROM句の副問い合わせの中でGROUP BY句を使用できています。

SELECT department_id, avg_salary
FROM (
    SELECT department_id,
           AVG(salary) AS avg_salary
    FROM employees
    GROUP BY department_id
) AS dept_avg

ですが本問での内容は「GROUP BY句で副問合せが使用できるか」なので
例えば下記のようなSQLが実行できるかを指してます。

SELECT department_id,
       AVG(salary) AS average_salary
FROM employees
GROUP BY (
    SELECT department_id
    FROM employees
);

このような形での副問合せの使用はできないため、本問の解答はGROUP BY句以外の選択となります。


コメント

2 24noriemon

2024/10/22 09:16

すんなり納得できました。ありがとうございます。 こういう誤認で失点することが多くて多くて。。

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

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