看到 decode(a, b, c, d) 这种写法,第一反应往往是「这是在解码什么」。其实在 Oracle 和部分数据库里,decode 是个条件判断函数,四个参数的意思和编码解码完全无关。

基本形式

DECODE(表达式, 值1, 结果1, 值2, 结果2, ..., 默认值)

它的逻辑是:把第一个参数和后面的值逐个比较,相等就返回对应的结果,全都不匹配就返回最后一个默认值。所以参数个数是 3、5、7 这样的奇数,四个参数严格来说不是标准用法。

那四个参数是什么情况

最常见的四参数写法其实是简化的条件判断:

DECODE(status, 1, '已支付', '未知')

这里四个参数分别是:要判断的字段 status、匹配值 1、匹配时返回的结果 '已支付'、以及不匹配时的默认值 '未知'。等价于一个只有两分支的 if。

另一种情况是把函数签名算进去,decode(字段, 条件, 真值, 假值),理解成 if-else 最直观。

多条件怎么写

DECODE(status, 1, '待付款', 2, '待发货', 3, '已完成', '其他')

这时候是七个参数,两两成对,最后一个是兜底。成对的值类型要一致,字符串和数字混着比,Oracle 会做隐式转换,结果可能不符合预期。

几个容易出错的地方

  • NULL 判断:DECODE 认为两个 NULL 是相等的,这一点和 = 号不一样,所以 DECODE(col, NULL, '空', '非空') 是能正常工作的。
  • 类型隐式转换:'1' 和 1 在比较时可能被当成相等,跨类型比较要显式转换。
  • 参数个数为偶数:少写一个默认值,语法直接报错。
  • 只在 Oracle 和部分兼容库可用:MySQL 没有这个函数,要换成 CASE WHEN 或者 IF。

可移植的替代写法

CASE status
  WHEN 1 THEN '待付款'
  WHEN 2 THEN '待发货'
  ELSE '其他'
END

CASE WHEN 是 SQL 标准,几乎所有数据库都支持,可读性也更好。新项目建议直接用 CASE,只有在维护 Oracle 老代码时才需要看懂 decode。

顺便区分一下:MySQL 里也有 decode(),但那是解密函数,配合 ENCODE 使用,和 Oracle 的 decode 完全是两回事。看到同名函数,先确认数据库类型。