IN条件
in_conditionはメンバーシップ条件です。メンバーシップ条件は、値のリストまたは副問合せ内のメンバーシップをテストします。
in_condition::=
expression_list::=
in_condition条件の上の方の書式(演算子の左辺に1つの式を指定する書式)を使用する場合は、expression_listの上の方の書式を使用する必要があります。この条件の下の方の書式(演算子の左辺に複数の式を指定する書式)を使用する場合は、expression_listの下の方の書式を使用し、各expression_list内の式は、演算子の左辺にある式と同じ数とデータ型で構成されている必要があります。expression_listには、最大1000個の式を指定できます。
expression_listの式は、INリスト内の順序で評価されるとはかぎりません。ただし、副問合せのSELECT構文のリストにある式は、指定された順序で評価されます。
関連項目:
表6-12に、IN条件の書式を示します。
表6-12 IN条件
| 条件の種類 | 操作 | 例 |
|---|---|---|
IN |
いずれかのメンバーとの等価テスト。 |
SELECT * FROM employees
WHERE job_id IN
('PU_CLERK','SH_CLERK')
ORDER BY employee_id;
SELECT * FROM employees
WHERE salary IN
(SELECT salary
FROM employees
WHERE department_id =30)
ORDER BY employee_id; |
NOT IN |
!= |
SELECT * FROM employees
WHERE salary NOT IN
(SELECT salary
FROM employees
WHERE department_id = 30)
ORDER BY employee_id;
SELECT * FROM employees
WHERE job_id NOT IN
('PU_CLERK', 'SH_CLERK')
ORDER BY employee_id; |
NOT IN演算子に続くリストの中のいずれかの項目がNULLの場合は、すべての行はFALSEまたは不明(UNKNOWN)と評価されます(行は戻されません)。たとえば、次の文ではそれぞれの行に対して文字列'True'が戻されます。
SELECT 'True' FROM employees WHERE department_id NOT IN (10, 20);
ただし、次の文では行は戻されません。
SELECT 'True' FROM employees
WHERE department_id NOT IN (10, 20, NULL);
この例で行が戻されないのは、WHERE句の条件が次のように評価されるためです。
department_id != 10 AND department_id != 20 AND department_id != null
3番目の条件でdepartment_idとNULLの比較が行われるため、この条件の結果がUNKNOWNとなり、式全体の結果がFALSE(department_idを持つ行が10または20と等しいため)となります。特に、NOT IN演算子が副問合せを参照するときは、このような動作を見逃してしまう可能性があることに注意してください。
また、NOT IN条件が、行を戻さない副問合せを参照する場合は、次のように、すべての行が戻されます。
SELECT 'True' FROM employees WHERE department_id NOT IN (SELECT 0 FROM DUAL WHERE 1=2);
文字引数の場合、IN条件は照合依存です。照合決定ルールによって、使用する照合が決まります。
関連項目:
IN条件の照合決定ルールは、『Oracle Databaseグローバリゼーション・サポート・ガイド』の付録Cを参照してください。
WHERE句のLEVELの制限事項
WHERE句の[NOT] IN条件の右辺が副問合せになっている場合、条件の左辺でLEVELは使用できません。ただし、FROM句の副問合せでLEVELを指定すると、同じ結果が得られます。たとえば、次の文は無効です。
SELECT employee_id, last_name FROM employees
WHERE (employee_id, LEVEL)
IN (SELECT employee_id, 2 FROM employees)
START WITH employee_id = 2
CONNECT BY PRIOR employee_id = manager_id;
ただし、次の文は、LEVEL情報を含む問合せをFROM句にカプセル化するため有効です。
SELECT v.employee_id, v.last_name, v.lev FROM
(SELECT employee_id, last_name, LEVEL lev
FROM employees v
START WITH employee_id = 100
CONNECT BY PRIOR employee_id = manager_id) v
WHERE (v.employee_id, v.lev) IN
(SELECT employee_id, 2 FROM employees); 
