SQLのwhere句でifによる条件切り替えは可能でしょうか?
SQLのwhere句の条件をifで分岐して切り替えることは可能?
IF文はストアドファンクションやプロシジャ、PL/SQL内で分岐をおこなうためのSQLです。
データベースの特定のカラムの内容などによってwhere句の条件を動的に切り替える目的で使うことはできません。
例えば、ストアドファンクションでif文を使用する場合は以下のようになります。以下はMySQLでの例です。
CREATE FUNCTION CheckNULL(name varchar(30)) RETURNS VARCHAR(20) BEGIN declare msg varchar(20); declare depname varchar(20); select dept_name into depname from departments where dept_no=num; if depname IS NULL then set msg = 'NULL'; else set msg=depname; END IF; END
【関連記事】
▶SQL if文のサンプルコード集 NULL判定や、Switch文のような分岐をする方法
if文はあくまで、変数などの特定の値を対象に分岐をおこなうためのものなんですね。
where句で動的に条件を切り替えるにはcase式
特定のカラムの値によって条件を切り替えるにはcase式を使います。以下の例は、gender(性別)がM(男性)ならemp_no<10010、F(女性)ならemp_no>20000をwhere句の条件に指定するSQLです。
select * from employees where case when gender='M' then emp_no < 10010 when gender='F' then emp_no > 20000 end limit 10; +--------+------------+------------+-----------+--------+------------+ | emp_no | birth_date | first_name | last_name | gender | hire_date | +--------+------------+------------+-----------+--------+------------+ | 10001 | 1953-09-02 | Georgi | Facello | M | 1986-06-26 | | 10003 | 1959-12-03 | Parto | Bamford | M | 1986-08-28 | | 10004 | 1954-05-01 | Chirstian | Koblick | M | 1986-12-01 | | 10005 | 1955-01-21 | Kyoichi | Maliniak | M | 1989-09-12 | | 10008 | 1958-02-19 | Saniya | Kalloufi | M | 1994-09-15 | | 20003 | 1953-04-11 | Munehiko | Coors | F | 1991-02-07 | | 20006 | 1953-09-21 | Geoff | Birnbaum | F | 1988-05-04 | | 20007 | 1964-06-21 | Deborah | Setia | F | 1991-06-11 | | 20009 | 1961-10-30 | Yakkov | Krybus | F | 1987-09-10 | | 20012 | 1960-08-27 | Pantung | Rodier | F | 1990-01-03 | +--------+------------+------------+-----------+--------+------------+ 10 rows in set (0.01 sec)
emp_no 10001~100010までのデータは以下のようになっています。
when gender=’M’の条件に当てはまるデータが5件、when gender=’F’に当てはまるemp_noが20000以上のデータが5件抽出されています。
mysql> select * from employees limit 10; +--------+------------+------------+-----------+--------+------------+ | 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 | | 10005 | 1955-01-21 | Kyoichi | Maliniak | M | 1989-09-12 | | 10006 | 1953-04-20 | Anneke | Preusig | F | 1989-06-02 | | 10007 | 1957-05-23 | Tzvetan | Zielinski | F | 1989-02-10 | | 10008 | 1958-02-19 | Saniya | Kalloufi | M | 1994-09-15 | | 10009 | 1952-04-19 | Sumant | Peac | F | 1985-02-18 | | 10010 | 1963-06-01 | Duangkaew | Piveteau | F | 1989-08-24 | +--------+------------+------------+-----------+--------+------------+ 10 rows in set (0.00 sec)
case式の対象をjoinなどで結合した他テーブルのカラムとすることも可能です。
まとめ
- where句でifを使って条件式を切り替えることはできない
- case式を使ってwhere句の条件式の切り替えが可能
- case式のwhenを複数記述することで、複数の条件式を指定可能。joinした他テーブルの参照もできる。