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 子句中使用会导致数据库无法利用索引进行扫描(和函数类似),在大数据量库中会导致性能问题。


相关推荐
Muscleheng2 小时前
Navicat连接postgresql时出现‘datlastsysoid does not exist‘报错
数据库·postgresql
kyriewen2 小时前
面试官让我查各部门工资最高的员工,我用AI三秒写出窗口函数,他愣了
后端·mysql·面试
小码工作室2 小时前
使用 HAVING 进行 MySQL 集合筛选
mysql
罗超驿3 小时前
18.事务的隔离性和隔离级别:MySQL面试高频考点全解析
数据库·mysql·面试
jran-3 小时前
Redis 命令
数据库·redis·缓存
小江的记录本3 小时前
【Java基础】Java 8-21新特性:JDK21 LTS:虚拟线程、模式匹配switch、结构化并发、序列集合(附《思维导图》+《面试高频考点清单》)
java·数据库·python·mysql·spring·面试·maven
GIS数据转换器4 小时前
农村生活污水治理智慧管控平台
大数据·人工智能·分布式·数据分析·生活·智慧城市
June`4 小时前
多线程redis下如何解决aof重写和rdb持久化的数据一致性问题
数据库·redis·缓存
木心术14 小时前
Windows系统下MySQL与AI工具集成方案:数据存储与调用实践
人工智能·windows·mysql
二宝哥4 小时前
离线安装maven
java·数据库·maven