首页 / 条件、空值和类型转换
DECODE 多值匹配
DECODE(expr, search1, result1, ..., default) 按值匹配返回结果,相当于简单的 CASE 表达式。MaxCompute 和 Spark 3.2 起支持这种写法;Hive 和 Flink 的 DECODE 是按字符集解码二进制,含义完全不同;其他引擎要改写为 CASE。
各引擎写法
| 引擎 | 支持 | 写法 | 说明 | 依据 |
|---|---|---|---|---|
| MaxCompute | 支持 | DECODE(expression, search, result[, search, result]...[, default]) | 没有匹配且没有 default 时返回 NULL。所有 result 的类型必须一致,search 与 expression 的类型也必须一致,否则报错。在 DECODE 中 NULL 与 NULL 视为相等。 | 官方文档 |
| Hologres | 需改写 | CASE expr WHEN search THEN result ... ELSE default END | 条件函数文档中没有 DECODE,用 CASE 改写。 | 官方文档 |
| StarRocks | 需改写 | CASE expr WHEN search THEN result ... ELSE default END | 函数列表中没有按值匹配的 DECODE,只有 base64、hex 等解码函数,用 CASE 改写。 | 官方文档 |
| Doris | 需改写 | CASE expr WHEN search THEN result ... ELSE default END | 条件函数中没有 DECODE,用 CASE 改写。 | 官方文档 |
| Hive | 需改写 | CASE expr WHEN search THEN result ... ELSE default END | Hive 的 decode(binary bin, string charset) 是按字符集把二进制解码为字符串,不能做多值匹配,需要用 CASE 改写。 | 官方文档 |
| Spark SQL | 支持 | decode(expr, search, result [, search, result ] ... [, default]) | 多值匹配写法 3.2.0 起支持。没有匹配且省略 default 时返回 NULL。同名的 decode(bin, charset) 用于按字符集解码。 | 官方文档 |
| Flink SQL | 需改写 | CASE expr WHEN search THEN result ... ELSE default END | DECODE(binary, string) 是按字符集解码二进制,不能做多值匹配,需要用 CASE 改写。 | 官方文档 |
迁移注意事项
- MaxCompute 的 DECODE 把 NULL 和 NULL 视为相等,DECODE(x, NULL, 0, 1) 在 x 为 NULL 时返回 0。改写成 CASE x WHEN NULL THEN 0 ... 永远不会匹配,要写成 CASE WHEN x IS NULL THEN 0 ...。
- Hive 和 Flink 也有 DECODE,但含义是字符集解码。把 MaxCompute 的多参数 DECODE 原样搬过去会报参数错误,必须改写成 CASE。
- Spark 3.2 之前只有字符集解码的 decode,多值匹配写法在旧版本中会报错。
- MaxCompute 要求所有 result 类型一致,例如 DECODE(x, 1, 1, 2, 'b') 会报错。改写成 CASE 后各引擎的隐式转换规则不同,建议显式 CAST。
示例
把状态码翻译成中文
SELECT DECODE(status, 1, '待支付', 2, '已支付', '其他') AS status_name FROM orders;SELECT CASE status WHEN 1 THEN '待支付' WHEN 2 THEN '已支付' ELSE '其他' END AS status_name FROM orders;SELECT CASE status WHEN 1 THEN '待支付' WHEN 2 THEN '已支付' ELSE '其他' END AS status_name FROM orders;SELECT CASE status WHEN 1 THEN '待支付' WHEN 2 THEN '已支付' ELSE '其他' END AS status_name FROM orders;SELECT CASE status WHEN 1 THEN '待支付' WHEN 2 THEN '已支付' ELSE '其他' END AS status_name FROM orders;SELECT decode(status, 1, '待支付', 2, '已支付', '其他') AS status_name FROM orders;SELECT CASE status WHEN 1 THEN '待支付' WHEN 2 THEN '已支付' ELSE '其他' END AS status_name FROM orders;