SQL大师之路 15 条件分支

在数据库查询中,我们经常会遇到需要根据不同条件返回不同结果的场景,虽然这些逻辑可以在应用层处理,但在数据库层面直接处理通常能减少应用层与数据库的交互次数,合并多次查询为一次,从而显著提高执行效率。


文章目录

    • [一、 CASE 表达式](#一、 CASE 表达式)
      • [1.1 简单 CASE 模式](#1.1 简单 CASE 模式)
      • [1.2 搜索 CASE 模式](#1.2 搜索 CASE 模式)
    • [二、 IF 函数](#二、 IF 函数)
    • [三、 使用要点](#三、 使用要点)

一、 CASE 表达式

CASE 是 MySQL的分支判断语句,它遵循标准 SQL 规范,具有极佳的通用性。下面用employees库演示其用法。

1.1 简单 CASE 模式

当需要进行简单的"等值匹配"时,类似于编程语言中的 switch-case。字段会依次与分支中的值进行比较。

语法:其中ELSE语句是可选的,如果没有匹配的分支同时没有ELSE语句,将返回null

sql 复制代码
CASE column_name
    WHEN value1 THEN result1
    WHEN value2 THEN result2
    ELSE default_result
END

案例:在 dept_emp 表中,部门编号如 d001, d005 并不直观,通过 CASE 我们可以快速将其映射为中文名称。

sql 复制代码
SELECT dept_no 部门编号,
      CASE dept_no
           WHEN 'd001' THEN '市场部'
           WHEN 'd002' THEN '财务部'
           WHEN 'd003' THEN '人力资源'
           WHEN 'd004' THEN '开发部'
           ELSE '其他部门'
       END 部门名称
FROM departments
LIMIT 10;

1.2 搜索 CASE 模式

搜索型 CASE 的强大之处在于它不局限于等值匹配,可以组合 AND、OR 以及各种逻辑运算符。

语法

sql 复制代码
CASE 
    WHEN condition1 THEN result1
    WHEN condition2 THEN result2
    ELSE default_result
END

案例:根据入职年份确定奖金系数,如果入职早于1990或者职位是'Senior Engineer'/'Manager' 取最高比例。

sql 复制代码
SELECT 
    e.emp_no, 
    e.first_name, 
    e.last_name, 
    CASE 
        WHEN e.hire_date < '1990-01-01' OR t.title IN ('Senior Engineer', 'Manager') THEN 0.8
        WHEN e.hire_date < '1995-01-01' THEN 0.6
		ELSE 0.4
    END 奖金系数
FROM employees e
JOIN titles t ON e.emp_no = t.emp_no;

二、 IF 函数

IF() 是 轻量级的三元运算符,非常适合处理 SQL 查询中简单的"二选一"逻辑。

语法
IF(expr1, expr2, expr3):如果 expr1 为 TRUE 返回 expr2,否则返回 expr3

案例:将employees表中的gender(包含值"F","M")转换为女/男。

sql 复制代码
SELECT 
    concat(last_name, ' ', first_name) 姓名,
    IF(gender='F', '女', '男') 性别
FROM employees
LIMIT 10;

三、 使用要点

  1. 短路特性 :CASE 会按顺序评估 WHEN 子句。一旦某个条件为真,它就会返回对应结果并停止后续评估。

  2. NULL 值的陷阱 :如果在 WHEN 条件中涉及可能为 NULL 的字段,务必结合 IS NULLIFNULL() 处理,否则 UNKNOWN 的判断结果会导致该条数据直接滑向 ELSE 分支。

  3. 性能与索引

    尽量在 SELECT 子句中使用,如果在 WHERE 子句中使用会导致数据库无法利用索引进行扫描(和函数类似),在大数据量库中会导致性能问题。


相关推荐
YOU OU20 分钟前
Redis基础常识与命令
数据库·redis·缓存
Database_Cool_3 小时前
OLTP 和 OLAP 区别详解:分析型数据库和事务型数据库怎么选(附阿里云 AnalyticDB MySQL 选型指南)
数据库·mysql·阿里云
爱写代码的阿森3 小时前
鸿蒙三方库 | harmony-utils之KvUtil键值型数据库操作详解
数据库·华为·harmonyos·鸿蒙·huawei
Database_Cool_3 小时前
单机 MySQL 迁移到分布式数据库方便吗?阿里云 PolarDB-X 100% MySQL 协议兼容零改造平滑迁移
数据库·分布式·mysql
姜太小白4 小时前
【MySQL】 索引优化实战:解决 WHERE 等值 + IS NULL 查询,TEXT 字段报错 1167 的完整指南
数据库·mysql
窝子面5 小时前
手搓最简前后端协作-node
javascript·数据库
吳所畏惧5 小时前
宝塔面板Redis密码修改指南:SSH命令修改 vs 面板UI界面修改,哪个更靠谱?
运维·服务器·数据库·redis·缓存·ssh
DFT计算杂谈5 小时前
无 Root 权限在 Tesla K80 零门槛部署 DeepSeek 大模型
linux·服务器·网络·数据库·机器学习
HPFBoy5 小时前
log4net 数据库存日志正确配置
数据库