助け合いフォーラム
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文です。

・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文です。

・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文です。

・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文です。

[集合演算子の優先順位]
・集合演算子には優先順位はない
・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;
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;
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 = '営業');
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);
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番目に指定されている列で昇順にソートされます。

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



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



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


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


複合問合せは次のように記述します。
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;
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;
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;
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;
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;
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;
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;
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;
UNION
SELECT salary FROM employees;

SQLを表示
SELECT salary FROM employees
UNION ALL
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;
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);
FROM departments
UNION ALL
(SELECT department_id, employee_id
FROM employees
MINUS
SELECT department_id, employee_id
FROM employees);
【誤字修正依頼】境界値の厳密性について
k
kidoyade
投稿日 2026/08/19
出題意図からは外れた指摘となりますが、問題文の「10年以内に入社した」という表現について確認をお願いいたします。
該当する選択肢では、すべて
「WHERE hiredate > SYSDATE - 365 * 10」となっておりますが、
厳密に言うと、「以内」の場合は「>=」が正しと思います。
ご確認・ご修正いただけますと幸いです。
この投稿に対して返信しませんか?