SQL Server の CASE ステートメントにおける OR 演算子の非対応
SQL Server の CASE ステートメントにおける OR 演算子の非対応について
SQL Server の CASE ステートメントは、条件分岐処理を行うための便利な機能です。しかし、OR 演算子を直接使用することはできません。
問題点
CASE ステートメントでは、WHEN 句で条件を指定し、THEN 句で条件が真の場合に実行される処理を記述します。しかし、OR 演算子を使って複数の条件をまとめて指定することはできない仕様になっています。
例えば、次の CASE ステートメントは、
CASE
WHEN age > 18 THEN '成人'
ELSE '未成年'
END
のように、年齢が 18 歳を超えている場合は "成人"、それ以外の場合は "未成年" という文字列を返します。
CASE
WHEN age > 18 OR is_student = 1 THEN '成人'
ELSE '未成年'
END
のように、年齢が 18 歳を超えている または 学生である場合は "成人" という文字列を返そうとしても、エラーが発生します。
解決策
OR 演算子を使いたい場合は、以下のいずれかの方法で代替することができます。
複数の WHEN 句を使用する
CASE
WHEN age > 18 THEN '成人'
WHEN is_student = 1 THEN '成人'
ELSE '未成年'
END
CASE ステートメントをネストする
CASE
WHEN age > 18 THEN '成人'
ELSE
CASE
WHEN is_student = 1 THEN '成人'
ELSE '未成年'
END
END
IIF 関数を使用する
IIF(age > 18 OR is_student = 1, '成人', '未成年')
CASE WHEN age > 18 THEN '成人' WHEN is_student = 1 THEN '成人' END
SQL Server の CASE ステートメントは OR 演算子を直接使用できないという制限があります。しかし、上記のような代替方法を用いることで、OR 演算子と同等の処理を実現することができます。
テーブル
CREATE TABLE Customers (
ID INT,
Name VARCHAR(50),
Age INT,
IsStudent BIT
);
データ
INSERT INTO Customers (ID, Name, Age, IsStudent)
VALUES
(1, 'John Doe', 20, 0),
(2, 'Jane Doe', 18, 1),
(3, 'Peter Smith', 30, 0);
SELECT ID, Name,
CASE
WHEN Age > 18 THEN '成人'
ELSE
CASE
WHEN IsStudent = 1 THEN '学生'
ELSE '未成年'
END
END AS Status
FROM Customers;
結果
ID | Name | Status
------- | -------- | --------
1 | John Doe | 成人
2 | Jane Doe | 学生
3 | Peter Smith | 未成年
IIF 関数
SELECT ID, Name,
IIF(Age > 18 OR IsStudent = 1, '成人', '未成年') AS Status
FROM Customers;
ID | Name | Status
------- | -------- | --------
1 | John Doe | 成人
2 | Jane Doe | 学生
3 | Peter Smith | 未成年
SELECT ID, Name,
CASE WHEN Age > 18 THEN '成人' WHEN IsStudent = 1 THEN '学生' END AS Status
FROM Customers;
ID | Name | Status
------- | -------- | --------
1 | John Doe | 成人
2 | Jane Doe | 学生
3 | Peter Smith | 未成年
これらのサンプルコードは、OR 演算子の代わりに CASE ステートメントの代替方法を使用する方法を示しています。
注意
CASE ステートメントのネストや IIF 関数は、CASE WHEN ステートメントよりも複雑で分かりにくくなる場合があります。そのため、可能な限り CASE WHEN ステートメントを使用することを推奨します。
OR 演算子の代替方法
COALESCE 関数は、最初の引数が NULL の場合に 2 番目の引数、2 番目の引数が NULL の場合に 3 番目の引数... というように、引数を順番に評価し、NULL ではない最初の引数を返します。
SELECT ID, Name,
COALESCE(
CASE WHEN Age > 18 THEN '成人' END,
CASE WHEN IsStudent = 1 THEN '学生' END,
'未成年'
) AS Status
FROM Customers;
UNION ALL ステートメントは、重複する行をすべて含めて、2 つのクエリ結果を結合します。
SELECT ID, Name, '成人' AS Status
FROM Customers
WHERE Age > 18
UNION ALL
SELECT ID, Name, '学生' AS Status
FROM Customers
WHERE IsStudent = 1
ORDER BY ID;
EXISTS 関数は、サブクエリが 1 行以上返した場合に TRUE を、0 行しか返さない場合に FALSE を返します。
SELECT ID, Name,
CASE WHEN EXISTS (
SELECT *
FROM Customers
WHERE Age > 18 AND ID = Customers.ID
) THEN '成人'
WHEN EXISTS (
SELECT *
FROM Customers
WHERE IsStudent = 1 AND ID = Customers.ID
) THEN '学生'
ELSE '未成年'
END AS Status
FROM Customers;
OR 演算子の代わりに使用できる方法はいくつかあります。それぞれの方法にはメリットとデメリットがあり、状況に合わせて適切な方法を選択する必要があります。
sql sql-server t-sql