本文翻译自13.4 Control Flow Functions
Table 13.6 Flow Control Operators
CASE | Case 运算符 |
IF() | if/else |
IFNULL() | if/else 是否为 NULL |
NULLIF | 当 expr1 = expr2 时返回 NULL |
CASE
CASE value WHEN [compare_value] THEN result
[WHEN [compare_value] THEN result ...]
[ELSE result]
END
CASE WHEN [condition] THEN result
[WHEN [condition] THEN result ...]
[ELSE result]
END
第一种方式是当 value = compare_value
时返回 result
. 第二种方式是返回首先遇到的 condition
为 true
时对应的 result
. 如果未能匹配任何值, 当有ELSE
子句时, 将会返回与其对应的 result
; 如果没有 ELSE
子句, 则会返回 NULL
.
mysql> SELECT CASE 1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'more' END;
+------------------------------------------------------------+
| CASE 1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'more' END |
+------------------------------------------------------------+
| one |
+------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT CASE WHEN 1>0 THEN 'true' ELSE 'false' END;
+--------------------------------------------+
| CASE WHEN 1>0 THEN 'true' ELSE 'false' END |
+--------------------------------------------+
| true |
+--------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT CASE BINARY 'B' WHEN 'a' THEN 1 WHEN 'b' THEN 2 END;
+-----------------------------------------------------+
| CASE BINARY 'B' WHEN 'a' THEN 1 WHEN 'b' THEN 2 END |
+-----------------------------------------------------+
| NULL |
+-----------------------------------------------------+
1 row in set (0.00 sec)
CASE
表达式能够返回任意类型的数据, 在实际使用中是依赖上下文中使用的数据类型. 例如在字符串上下文中, 返回的数据类型是字符串. 如果在数字上下文中, 返回的数据类型可能是 decimal
, real
, 或者 integer
.
IF(expr1, expr2, expr3)
如果 expr1
为 TRUE
(expr1 <> 0
and expr1 <> NULL
), 则 IF()
函数将返回 expr2
; 否则将返回 expr3
. IF()
函数根据其上下文决定返回 数字 或 字符串 类型的数据.
mysql> SELECT IF(1 > 2, 2, 3);
+-----------------+
| IF(1 > 2, 2, 3) |
+-----------------+
| 3 |
+-----------------+
1 row in set (0.00 sec)
mysql> SELECT IF(1 < 2, 'yes', 'no');
+------------------------+
| IF(1 < 2, 'yes', 'no') |
+------------------------+
| yes |
+------------------------+
1 row in set (0.00 sec)
mysql> SELECT IF(STRCMP('test', 'test1'), 'no', 'yes');
+------------------------------------------+
| IF(STRCMP('test', 'test1'), 'no', 'yes') |
+------------------------------------------+
| no |
+------------------------------------------+
1 row in set (0.00 sec)
如果 expr2
或 expr3
中有一个类型为 NULL
, 那么 IF()
函数的返回类型是另外一个非 NULL
表达式的类型.
IF()
默认返回值类型评定规则(在将数据存储到临时表时可能非常重要):
expr2 或 expr3 返回字符串 | 字符串 |
expr2 或 expr3 返回浮点数 | 浮点数 |
expr2 或 expr3 返回整型 | 整型 |
当 expr2
或 expr3
都是字符串时, 如果他们之中有一个是字符大小写敏感的, 那么返回类型也是大小写敏感的.
IFNULL(expr1, expr2)
如果 expr1
不是 NULL
, 那么 IFNULL()
返回 expr1
, 否则返回 expr2
. IFNULL()
根据上下文确定其返回数字或字符串.
mysql> SELECT IFNULL(1, 0);
+--------------+
| IFNULL(1, 0) |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)
mysql> SELECT IFNULL(NULL, 10);
+------------------+
| IFNULL(NULL, 10) |
+------------------+
| 10 |
+------------------+
1 row in set (0.00 sec)
mysql> SELECT IFNULL(1/0, 10);
+-----------------+
| IFNULL(1/0, 10) |
+-----------------+
| 10.0000 |
+-----------------+
1 row in set (0.00 sec)
mysql> SELECT IFNULL(1/0, 'yes');
+--------------------+
| IFNULL(1/0, 'yes') |
+--------------------+
| yes |
+--------------------+
1 row in set (0.00 sec)
IFNULL(expr1, expr2)
的默认返回值类型规则是非常 普通 的, 取值顺序是 STRING
, REAL
, INTEGER
. 考虑当 IFNULL()
存在于创建新表时或 MySQL 必须创建临时表存储数据时:
mysql> CREATE TABLE tmp SELECT IFNULL(1,'test') AS test;
Query OK, 1 row affected (0.05 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> DESCRIBE tmp;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| test | varbinary(4) | NO | | | |
+-------+--------------+------+-----+---------+-------+
1 row in set (0.01 sec)
在这个示例中, test
列的类型是 VARBINARY(4)
.
NULLIF(expr1, expr2)
当 expr1 = expr2
为真时返回 NULL
, 否则返回 expr1
. 与 CASE WHEN expr1 = expr2 THEN NULL ELSE expr1 END
等效.
mysql> SELECT NULLIF(1, 1);
+--------------+
| NULLIF(1, 1) |
+--------------+
| NULL |
+--------------+
1 row in set (0.00 sec)
mysql> SELECT NULLIF(1, 2);
+--------------+
| NULLIF(1, 2) |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)
注意: 当两个参数值不相等时, expr1
会执行两次.