本文翻译自13.4 Control Flow Functions

Table 13.6 Flow Control Operators

CASECase 运算符
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. 第二种方式是返回首先遇到的 conditiontrue 时对应的 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)

如果 expr1TRUE(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)

如果 expr2expr3 中有一个类型为 NULL, 那么 IF() 函数的返回类型是另外一个非 NULL 表达式的类型.

IF() 默认返回值类型评定规则(在将数据存储到临时表时可能非常重要):

expr2expr3 返回字符串字符串
expr2expr3 返回浮点数浮点数
expr2expr3 返回整型整型

expr2expr3 都是字符串时, 如果他们之中有一个是字符大小写敏感的, 那么返回类型也是大小写敏感的.

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 会执行两次.

05-11 15:10