助け合いフォーラム

Oracle DB

Oracle Master Silver SQL 2019(1Z0-071)
問題ID : 26899
問題を開く
部署が「営業」で、10年以内に入社した給与が30万円以上の従業員を出力します。
どの問合せを使用しますか。

正解

SELECT department_id, employee_name, hiredate, salary FROM employees
WHERE hiredate > SYSDATE - 365 * 10
INTERSECT
SELECT department_id, employee_name, hiredate, salary FROM employees
WHERE salary >= 300000
MINUS
SELECT department_id, employee_name, hiredate, salary FROM employees
WHERE department_id NOT IN (SELECT department_id FROM departments WHERE department_name = '営業');

解説

集合演算子を用いて複合問合せを行うには、いくつかのガイドラインがあります。

[集合演算子の優先順位]
・集合演算子には優先順位はない
・1つのSQL文に複数の集合演算子が使用されている場合は、SQL文の先頭から順番に複合問合せが実行される
・優先順位を明示的に指定したい場合は、()括弧を用いて優先順位を指定する

各条件を以下のように定義して、選択肢を1つずつ確認してみましょう(SQL文の実行日は2015年の1月です)。

条件1 : 部署が「営業」
条件2 : 10年以内に入社
条件3 : 給与が30万円以上

・SELECT department_id, employee_name, hiredate, salary FROM employees
 WHERE department_id = (SELECT department_id FROM departments WHERE department_name = '営業')
 UNION
 SELECT department_id, employee_name, hiredate, salary FROM employees
 WHERE hiredate > SYSDATE - 365 * 10
 INTERSECT
 SELECT department_id, employee_name, hiredate, salary FROM employees
 WHERE salary >= 300000;
「条件1 UNION 条件2 INTERSECT 条件3」の順に実行されますが、UNION演算子は条件1と条件2それぞれの結果を統合しますので、誤ったSQL文です。


SQLを表示
SELECT department_id, employee_name, hiredate, salary FROM employees
WHERE department_id = (SELECT department_id FROM departments WHERE department_name = '営業')
UNION
SELECT department_id, employee_name, hiredate, salary FROM employees
WHERE hiredate > SYSDATE - 365 * 10
INTERSECT
SELECT department_id, employee_name, hiredate, salary FROM employees
WHERE salary >= 300000;


・SELECT department_id, employee_name, hiredate, salary FROM employees
 WHERE department_id = (SELECT department_id FROM departments WHERE department_name = '営業')
 INTERSECT
 SELECT department_id, employee_name, hiredate, salary FROM employees
 WHERE hiredate > SYSDATE - 365 * 10
 UNION ALL
 SELECT department_id, employee_name, hiredate, salary FROM employees
 WHERE salary >= 300000;
「条件1 INTERSECT 条件2 UNION ALL 条件3」の順に実行されますが、UNION ALL演算子は条件1, 2と条件3の結果を統合しますので、誤ったSQL文です。


SQLを表示
SELECT department_id, employee_name, hiredate, salary FROM employees
WHERE department_id = (SELECT department_id FROM departments WHERE department_name = '営業')
INTERSECT
SELECT department_id, employee_name, hiredate, salary FROM employees
WHERE hiredate > SYSDATE - 365 * 10
UNION ALL
SELECT department_id, employee_name, hiredate, salary FROM employees
WHERE salary >= 300000;


・SELECT department_id, employee_name, hiredate, salary FROM employees
 WHERE hiredate > SYSDATE - 365 * 10
 INTERSECT
 SELECT department_id, employee_name, hiredate, salary FROM employees
 WHERE salary >= 300000
 MINUS
 SELECT department_id, employee_name, hiredate, salary FROM employees
 WHERE department_id NOT IN (SELECT department_id FROM departments WHERE department_name = '営業');
「条件2 INTERSECT 条件3 MINUS 条件1でない」の順に実行され、条件2, 3の結果からMINUS演算子で条件1でない問合せ結果を除いた結果を表示します。正しいSQL文です。


SQLを表示
SELECT department_id, employee_name, hiredate, salary FROM employees
WHERE hiredate > SYSDATE - 365 * 10
INTERSECT
SELECT department_id, employee_name, hiredate, salary FROM employees
WHERE salary >= 300000
MINUS
SELECT department_id, employee_name, hiredate, salary FROM employees
WHERE department_id NOT IN (SELECT department_id FROM departments WHERE department_name = '営業');


・SELECT department_id, employee_name, hiredate, salary FROM employees
 WHERE department_id NOT IN (SELECT department_id FROM departments WHERE department_name = '営業')
 MINUS
 (SELECT department_id, employee_name, hiredate, salary FROM employees
 WHERE hiredate > SYSDATE - 365 * 10
 INTERSECT
 SELECT department_id, employee_name, hiredate, salary FROM employees
 WHERE salary >= 300000);
「条件1でない MINUS (条件2 INTERSECT 条件3)」のように()括弧で囲まれた部分から順に実行されますが、条件1でない問合せ結果からMINUS演算子で条件2, 3の結果を除いた結果となり、誤ったSQL文です。


SQLを表示
SELECT department_id, employee_name, hiredate, salary FROM employees
WHERE department_id NOT IN (SELECT department_id FROM departments WHERE department_name = '営業')
MINUS
(SELECT department_id, employee_name, hiredate, salary FROM employees
WHERE hiredate > SYSDATE - 365 * 10
INTERSECT
SELECT department_id, employee_name, hiredate, salary FROM employees
WHERE salary >= 300000);

参考

集合演算子を用いて、複数の問合せの結果を1つにまとめて表示する問合せを複合問合せといいます。
複合問合せは次のように記述します。

 SELECT文 1
  {UNION | UNION ALL | INTERSECT | MINUS}
 SELECT文 2

複合問合せで使用する集合演算子は次の通りです。



4つの演算子のうち、UNION ALL演算子以外の演算子を使用した複合問合せでは、問合せの結果がSELECT句の1番目に指定されている列で昇順にソートされます。


 
SQLを表示
SELECT department_id, manager_id
FROM departments
 INTERSECT
SELECT department_id, employee_id
FROM employees;

SELECT department_id, manager_id
FROM departments
 UNION ALL
SELECT department_id, employee_id
FROM employees;


集合演算子を用いて複合問合せを行うには、いくつかのガイドラインがあります。

[SELECT句の指定]
・複合問合せの列見出しは1つ目の問合せに指定された列名が使用される(それぞれの問合せで指定される列名が異なっていても良い)
・2つの問合せでSELECT句に指定する列や式の数を同数にしなければならない
・2つの問合せでSELECT句に指定する列や式のデータ型を同じ、もしくは同じデータ型グループにしなければならない(ただし、サイズは異なっていても良い)


 
SQLを表示
SELECT department_id, manager_id
FROM departments
 INTERSECT
SELECT department_id, employee_id
FROM employees;


 
SQLを表示
SELECT department_id, manager_id
FROM departments
 INTERSECT
SELECT department_id, employee_id, employee_name
FROM employees;


 
SQLを表示
SELECT department_id, manager_id
FROM departments
 INTERSECT
SELECT department_id, employee_name
FROM employees;


[ORDER BY句の使用]
・ORDER BY句は複合問合せの最後の問合せに指定する
・ORDER BY句には最初の問合せに指定されている列名や列別名を指定する


 
SQLを表示
SELECT department_id dept, manager_id mgr
FROM departments
 INTERSECT
SELECT department_id, employee_id
FROM employees
ORDER BY dept DESC;


 
SQLを表示
SELECT department_id dept, manager_id mgr
FROM departments
ORDER BY dept DESC
 INTERSECT
SELECT department_id, employee_name
FROM employees;


 
SQLを表示
SELECT department_id dept, manager_id mgr
FROM departments
 INTERSECT
SELECT department_id dept2, employee_id emp
FROM employees
ORDER BY employee_id;


[NULL値の扱い]
・NULL値は無視されない
・UNION ALL演算子以外の演算子を使用した複合問合せでは、重複したNULL値は排除される


 
SQLを表示
SELECT salary FROM employees
 UNION
SELECT salary FROM employees;


 
SQLを表示
SELECT salary FROM employees
 UNION ALL
SELECT salary FROM employees;


[集合演算子の優先順位]
・集合演算子には優先順位はない
・1つのSQL文に複数の集合演算子が使用されている場合は、SQL文の先頭から順番に複合問合せが実行される
・優先順位を明示的に指定したい場合は、()括弧を用いて優先順位を指定する


 
SQLを表示
SELECT department_id, manager_id
FROM departments
 UNION ALL
SELECT department_id, employee_id
FROM employees
 MINUS
SELECT department_id, employee_id
FROM employees;



 
SQLを表示
SELECT department_id, manager_id
FROM departments
 UNION ALL
(SELECT department_id, employee_id
FROM employees
 MINUS
SELECT department_id, employee_id
FROM employees);
上に戻る

【誤字修正依頼】境界値の厳密性について

投稿日 2026/08/19

出題意図からは外れた指摘となりますが、問題文の「10年以内に入社した」という表現について確認をお願いいたします。

該当する選択肢では、すべて
「WHERE hiredate > SYSDATE - 365 * 10」となっておりますが、
厳密に言うと、「以内」の場合は「>=」が正しと思います。

ご確認・ご修正いただけますと幸いです。

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