DECODE
DECODE 是 Oracle 数据库的专有函数, MySQL 和 SQL Server 并不原生支持 DECODE 函数。
默认语法
sql
DECODE(expr, search1, result1, search2, result2, ..., default_result)
由此可知, 最后一个是默认值
sql
SELECT employee_id,
DECODE(department_id,
10, salary * 0.1,
20, salary * 0.15,
30, salary * 0.2,
salary * 0.05) AS bonus
FROM employees;
sql
在这里插入代码片
奖金计算方式,
department_id: 10, 薪资0.1; 20,薪资0.15
sql
SELECT employee_id,
DECODE(commission_pct, NULL, 0, commission_pct) AS commission_percentage
FROM employees;
上面的代码是处理空值的, 如果为null,则是0, 否则输出原值
功能限制:DECODE 只能进行等值判断(=),不支持大于(>)、小于(<)或 IN 等范围比较。如果逻辑复杂,CASE WHEN 会更加灵活
CASE WHEN
正如前面提到的,CASE WHEN 是 SQL 中用于实现条件逻辑的标准表达式,它不仅是 DECODE 函数的最佳替代方案,而且功能更加强大和灵活.
sql
SELECT name, salary,
CASE performance_level
WHEN 'High' THEN 'Performance is excellent'
WHEN 'Medium' THEN 'Performance is satisfactory'
WHEN 'Low' THEN 'Performance needs improvement'
ELSE 'Performance level not specified'
END AS performance_description`在这里插入代码片`
FROM employees;
sql
SELECT ProductNumber, Name,
CASE
WHEN ListPrice = 0 THEN 'Mfg item - not for resale'
WHEN ListPrice < 50 THEN 'Under $50'
WHEN ListPrice >= 50 AND ListPrice < 250 THEN 'Under $250'
WHEN ListPrice >= 250 AND ListPrice < 1000 THEN 'Under $1000'
ELSE 'Over $1000'
END AS Price_Range
FROM Production.Product;
- 短路求值:CASE 表达式会按照 WHEN 子句出现的顺序进行评估。一旦遇到第一个计算结果为 TRUE 的条件,就会立即返回对应的结果,并停止后续条件的计算。
- ELSE 子句是可选的:如果所有的 WHEN 条件都不满足,且没有提供 ELSE 子句,CASE 表达式将默认返回 NULL 值。
- 应用广泛:除了 SELECT 查询,CASE WHEN 还可以用在 UPDATE、DELETE、WHERE、ORDER BY 和 HAVING 等子句中。
- 跨数据库兼容:CASE WHEN 是 ANSI SQL 标准的一部分,这意味着它在 Oracle、MySQL、SQL Server、PostgreSQL 等几乎所有主流数据库中都能通用。
case when 后面 表达式
在 SQL 中,CASE WHEN 表达式非常灵活,它支持两种主要的语法结构,而 WHEN 后面的条件判断几乎可以包含 SQL 中所有的逻辑表达式
等值比较
sql
CASE status
WHEN 1 THEN '待处理'
WHEN 2 THEN '已完成'
ELSE '未知'
END
范围与条件判断
sql
CASE
WHEN age >= 18 AND age <= 60 THEN '成年人'
WHEN age > 60 THEN '老年人'
ELSE '未成年人'
END
逻辑组合
sql
CASE
WHEN department = 'IT' AND level >= 3 THEN '高级IT'
WHEN department = 'HR' OR department = 'Finance' THEN '后台支持'
ELSE '普通员工'
END
空值判断(IS NULL)
sql
CASE WHEN t2.mc_id IS NOT NULL THEN '1' ELSE '2' END AS our_type
sql
CASE
WHEN phone_number IS NULL THEN '未填写'
WHEN phone_number != '' THEN '已填写'
ELSE '无效号码'
END
嵌套子查询
sql
CASE
WHEN EXISTS (SELECT 1 FROM orders WHERE orders.user_id = users.id) THEN '有订单用户'
ELSE '无订单用户'
END
字符串匹配
sql
CASE
WHEN email LIKE '%@gmail.com' THEN 'Gmail用户'
WHEN email LIKE '%@qq.com' THEN 'QQ用户'
ELSE '其他邮箱'
END
结合内置函数
sql
CASE
WHEN LENGTH(password) < 8 THEN '密码太短'
WHEN TO_CHAR(create_time, 'YYYY') = '2024' THEN '今年注册'
ELSE '正常'
END