SQLのinの構文、右辺にNULLが入っているときの扱い、DBMSごとに異なる右辺に記述できる式の数についてまとめています。
SQL inの構文
SQLのin演算子は、複数の値の中に一致するものが存在すれば真(1)、存在しなければ(0)を返します。
mysql> select 1 in (1,2); +------------+ | 1 in (1,2) | +------------+ | 1 | +------------+ 1 row in set (0.00 sec) mysql> select 0 in (1,2); +------------+ | 0 in (1,2) | +------------+ | 0 | +------------+ 1 row in set (0.00 sec) mysql> select 'a' in ('a','b'); +------------------+ | 'a' in ('a','b') | +------------------+ | 1 | +------------------+ 1 row in set (0.00 sec)
SQLのwhere条件にinを使う例は以下の通りです。employeesテーブルのemp_noが10001、10002、10003、10004のデータを抽出します。
mysql> select * from employees where emp_no in ( 10001, 10002, 10003, 10004 ); +--------+------------+------------+-----------+--------+------------+ | emp_no | birth_date | first_name | last_name | gender | hire_date | +--------+------------+------------+-----------+--------+------------+ | 10001 | 1953-09-02 | Georgi | Facello | M | 1986-06-26 | | 10002 | 1964-06-02 | Bezalel | Simmel | F | 1985-11-21 | | 10003 | 1959-12-03 | Parto | Bamford | M | 1986-08-28 | | 10004 | 1954-05-01 | Chirstian | Koblick | M | 1986-12-01 | +--------+------------+------------+-----------+--------+------------+ 4 rows in set (0.00 sec)
not inと指定すると、指定した値と一致しないものを抽出することが可能です。以下の例はdepartments(部署)テーブルのdept_name(部署名)が、Marketing、Sales、Development以外のデータを抽出します。
mysql> SELECT * FROM departments where dept_name not in ('Marketing','Sales', 'Development'); +---------+--------------------+ | dept_no | dept_name | +---------+--------------------+ | d009 | Customer Service | | d002 | Finance | | d003 | Human Resources | | d004 | Production | | d006 | Quality Management | | d008 | Research | +---------+--------------------+ 6 rows in set (0.04 sec)
【関連記事】
▶SQL in句のサンプルコード集 複数カラムの指定方法とは?
SQLのinはNULLが入っていると、一致しない場合にNULLが返ってくる
in演算子を使う場合は、NULLの扱いに注意です。右辺にNULLが入っていた場合、「どれにも一致しない場合」は、NULLが返ってきます。
mysql> select 1 in ( 1,2,3,NULL ); +---------------------+ | 1 in ( 1,2,3,NULL ) | +---------------------+ | 1 | +---------------------+ 1 row in set (0.00 sec) mysql> select 0 in ( 1,2,3,NULL ); +---------------------+ | 0 in ( 1,2,3,NULL ) | +---------------------+ | NULL | +---------------------+ 1 row in set (0.00 sec)
DBMSごとのin演算子の違い
Oracleのin演算子
以下は、Oracleで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;
なお、inの左辺にある式と右辺は同じデータ型で構成されている必要があります。式は、最大1000個の式を指定できます。
SQL Serverのin演算子
以下は、SQL ServerでINを使う例です。
-- Uses AdventureWorks SELECT p.FirstName, p.LastName, e.JobTitle FROM Person.Person AS p JOIN HumanResources.Employee AS e ON p.BusinessEntityID = e.BusinessEntityID WHERE e.JobTitle IN ('Design Engineer', 'Tool Designer', 'Marketing Assistant'); GO
関連)IN (Transact-SQL) – SQL Server | Microsoft Docs
かっこで囲んだINの右辺に極端に多くの値 (コンマで区切られた数千単位の値) を指定すると、リソースが消費されてエラー 8623 または 8632 が返される場合があります。 あまりにも多くの値を指定しなければならない場合は、INリストにサブクエリを使用します。
DBMSごとのin演算子の扱いの違い
MySQLのin演算子
MySQLでINを使う例は以下の通り。
mysql> SELECT 2 IN (0,3,5,7); -> 0 mysql> SELECT 'wefwf' IN ('wee','wefwf','weg'); -> 1
関連)MySQL :: MySQL 5.6 リファレンスマニュアル :: 12.3.2 比較関数と演算子
MySQLのINの右辺に使える値の数は、max_allowed_packet 値によって制限されます。max_allowed_packetの値は以下のように確認可能です。
mysql> select @@max_allowed_packet; +----------------------+ | @@max_allowed_packet | +----------------------+ | 67108864 | +----------------------+ 1 row in set (0.00 sec)
PostgreSQLのin演算子
PostgreSQLのINを使う例は以下の通り。
expression = value1 OR expression = value2 OR ...
PostgreSQLの公式ドキュメントには、右辺に使える値の数に関する記述は特にありませんでした。
まとめ
- inは、複数の値に一致するものが含まれるかどうかを判定する演算子。
- inの右辺にNULLが入っている場合、一致しない場合の値はNULLになる。
- inの右辺に記述できる数はDBMSによって違いがある。