乐途乐途
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
  • 学习路径
  • 第1章 数据库基础与安装

    • MySQL 简介
    • MySQL 5.6 到 5.7 到 8.0 关键差异速查
    • 安装 MySQL 5.7
    • 连接与断开服务器
    • 创建数据库
    • 创建数据表
    • 数据库与数据表
    • 加载数据
    • 获取数据库信息
    • 批处理模式
    • SHOW 语句汇总
    • FLUSH 与 RESET 语句
    • my.cnf 核心参数
    • 字符集与排序规则
  • 第2章 SQL基础查询

    • SELECT
    • WHERE
    • ORDER BY
    • LIMIT
    • COUNT
    • 聚合函数
    • 比较运算符
    • 逻辑运算符
    • 算术运算符
    • 模式匹配
    • NULL 值处理
    • UPDATE
    • DELETE
    • REPLACE
    • SELECT INTO
  • 第3章 数据类型与运算符

    • 数值类型
    • 字符串类型
    • 日期时间类型
    • BIT 类型
    • ENUM 类型
    • SET 类型
    • JSON 类型
    • 类型转换
  • 第4章 函数与表达式

    • 字符串函数
    • 数值函数
    • 日期函数
    • 全文检索函数
  • 第5章 高级查询与子查询

    • JOIN
    • 子查询
    • UNION
    • GROUP BY
    • HAVING
    • DISTINCT
  • 第6章 表与索引

    • 数据定义语言
    • 修改表结构
    • 视图
    • 修改视图与检查选项
    • 外键
    • 索引
    • 唯一索引
    • 复合索引
    • 存储引擎对比
    • 分区表
    • 第一范式与第二范式
    • 第三范式与 BC 范式
    • 反范式设计
  • 第7章 存储过程与函数

    • 存储过程
    • 存储函数
    • 变量
    • 流程控制
    • 游标
    • 预处理语句
  • 第8章 事务与锁

    • 事务
    • 事务隔离级别
    • 锁机制
    • MVCC
    • 死锁专题分析
    • LOCK TABLES
    • XA 事务
  • 第9章 用户管理与安全

    • 用户管理
    • 权限管理
    • 角色
    • SQL 注入防范
  • 第10章 性能优化入门

    • 执行计划
    • 索引优化
    • 查询优化
    • 查询优化器提示
    • 慢查询日志
    • InnoDB 深入机制
    • InnoDB 专项优化
    • Performance Schema
    • sys Schema
  • 第11章 复制与高可用

    • 主从复制原理
    • 半同步复制配置
    • binlog 开启与 point-in-time 恢复
    • mysqldump 全库备份
    • mysqldump 单表与条件备份
    • mysqldump 恢复与导入
    • xtrabackup 全量热备
    • xtrabackup 准备与恢复
    • xtrabackup 增量与流式备份
  • 第12章 触发器与事件

    • 触发器
    • 事件调度器
  • 参考

    • MySQL 5.7 专业术语大全
    • MySQL 5.7 关键字与保留字大全

逻辑运算符

导学

实际业务中,筛选条件很少只有一个。"年龄大于 18 且部门是技术部"、"状态为 0 或 2 且未删除"——这类复合条件需要逻辑运算符来组合。

定义

逻辑运算符:用于组合多个条件表达式,返回 1(真)、0(假)或 NULL(未知)。MySQL 支持 AND、OR、NOT、XOR 四种逻辑运算。

真值表

条件1条件2ANDORXOR
TRUETRUETRUETRUEFALSE
TRUEFALSEFALSETRUETRUE
TRUENULLNULLTRUENULL
FALSEFALSEFALSEFALSEFALSE
FALSENULLFALSENULLNULL
NULLNULLNULLNULLNULL

演示数据准备

DROP TABLE IF EXISTS employees;

CREATE TABLE employees (
    emp_id INT PRIMARY KEY AUTO_INCREMENT,
    emp_name VARCHAR(20),
    dept VARCHAR(20),
    score DECIMAL(5,2)
);

INSERT INTO employees (emp_name, dept, score) VALUES
('大翔', '技术部', 100),
('白歌', '技术部', NULL);

当前 employees 表中的完整数据如下:

emp_idemp_namedeptscore
1大翔技术部100
2白歌技术部NULL

SQL 示例

场景一:AND 组合条件

当前数据状态:见上文 employees 表完整数据。

执行语句:

SELECT emp_name, dept, score FROM employees
WHERE dept = '技术部' AND score >= 90;

操作后结果:

emp_namedeptscore
大翔技术部100

结果解读:AND 要求两个条件同时为真。技术部且绩效大于等于 90 的员工只有大翔,因此只返回 1 条。如果加入第三个条件:

SELECT emp_name, dept, score FROM employees
WHERE dept = '技术部' AND score >= 90 AND emp_name = '大翔';

操作后结果:

emp_namedeptscore
大翔技术部100

结果解读:三个条件同时满足的只有大翔。白歌虽然属于技术部,但 score 为 NULL(不满足 >= 90),因此不返回。

场景二:OR 组合条件

当前数据状态:见上文 employees 表完整数据。

执行语句:

SELECT emp_name, dept, score FROM employees
WHERE dept = '产品部' OR score IS NULL;

操作后结果:

emp_namedeptscore
白歌技术部NULL

结果解读:满足任一条件即可。白歌的 score 为 NULL,因此 1 条被返回。当前表中没有产品部员工。

场景三:优先级陷阱(经典面试题)

当前数据状态:见上文 employees 表完整数据。

执行语句(错误写法):

-- 危险:本意是"技术部且绩效为 NULL,或者产品部且绩效为 NULL"
-- 实际执行:"(技术部且 NULL) 或 产品部"——语义错误
SELECT emp_name, dept, score FROM employees
WHERE dept = '技术部' AND score IS NULL OR dept = '产品部';

操作后结果:

emp_namedeptscore
白歌技术部NULL

结果解读:由于 AND 优先级高于 OR,实际执行的是 WHERE (dept = '技术部' AND score IS NULL) OR dept = '产品部'。当前表中没有产品部员工,因此只有白歌被返回。

正确写法(如果本意是"技术部或产品部中,绩效为 NULL 的人"):

SELECT emp_name, dept, score FROM employees
WHERE (dept = '技术部' OR dept = '产品部') AND score IS NULL;

操作后结果:

emp_namedeptscore
白歌技术部NULL

结果解读:加括号后先判断部门(技术部或产品部),再判断绩效是否为 NULL。当前表中没有产品部员工,因此只有白歌满足条件。

优先级规则:NOT > AND > OR。建议始终用括号显式分组,不要依赖默认优先级。

场景四:NOT 取反

当前数据状态:见上文 employees 表完整数据。

执行语句:

SELECT emp_name, dept FROM employees
WHERE NOT dept = '技术部';
-- 等价于
-- WHERE dept <> '技术部';

操作后结果:

emp_namedept

结果解读:NOT 对条件取反,排除了技术部的大翔和白歌。当前表中没有产品部员工,因此返回空结果。NOT dept = '技术部' 等价于 dept <> '技术部'。

再看一个 NOT 与 IN 结合的例子:

SELECT emp_name, dept FROM employees WHERE dept NOT IN ('技术部');

操作后结果:

emp_namedept

结果解读:NOT IN 排除列表中的值,返回部门不是技术部的员工。当前表中没有产品部员工,因此返回空结果。

场景五:IN 是 OR 的语法糖

当前数据状态:见上文 employees 表完整数据。

执行语句:

-- 以下两条完全等价
SELECT emp_name FROM employees WHERE dept = '技术部' OR dept = '产品部';
SELECT emp_name FROM employees WHERE dept IN ('技术部', '产品部');

操作后结果(两者相同):

emp_name
大翔
白歌

结果解读:IN 是多值 OR 的简洁写法。当选项很多时,IN 的可读性远好于一长串 OR。MySQL 5.7 优化器通常会将两者优化为相同的执行计划。

场景六:XOR(异或)

当前数据状态:见上文 employees 表完整数据。

执行语句:

SELECT emp_name, dept, score FROM employees
WHERE (score IS NULL) XOR (dept = '产品部');

操作后结果:

emp_namedeptscore
白歌技术部NULL

结果解读:XOR 要求两个条件有且仅有一个为真。让我们逐行分析:

  • 大翔:score IS NULL(假),dept = '产品部'(假)→ XOR 为假(未返回)
  • 白歌:score IS NULL(真),dept = '产品部'(假)→ XOR 为真 ✓

大翔因两个条件都为假而被排除,白歌因恰好一个条件为真而被返回。

短路求值

MySQL 在求值逻辑表达式时采用短路求值(Short-circuit Evaluation):

  • AND:若左侧为 FALSE,右侧不再执行
  • OR:若左侧为 TRUE,右侧不再执行
-- 如果 dept <> '技术部',右侧的复杂函数不会执行
WHERE dept = '技术部' AND LENGTH(phone) = 11;

这意味着应将筛选性强的条件放在左侧,可能减少不必要的计算。

常见误区

误区正解
AND 和 OR 优先级相同AND 优先级高于 OR,混用必须加括号。
WHERE NOT col1 = 1 AND col2 = 2解析为 WHERE (NOT col1 = 1) AND col2 = 2,而非 NOT (col1 = 1 AND col2 = 2)。
用 OR 连接索引列性能一定差MySQL 5.7 的索引合并(Index Merge)可以优化某些 OR 查询。
XOR 很常用实际业务中极少使用,通常用 (a AND NOT b) OR (NOT a AND b) 替代。

面试考点

Q:AND 和 OR 的优先级?

NOT > AND > OR。建议始终用括号显式分组,增强可读性并避免歧义。

Q:下面这条 SQL 的查询条件是什么?

WHERE a = 1 OR b = 2 AND c = 3 实际等价于 WHERE a = 1 OR (b = 2 AND c = 3)。若要表达 (a = 1 OR b = 2) AND c = 3,必须加括号。

Q:MySQL 的 XOR 在实际中常用吗?

极少使用。XOR 表达"二者有且仅有一个为真",这种业务场景不多。通常用 (a AND NOT b) OR (NOT a AND b) 替代,可读性更好。

Q:短路求值对性能有什么影响?

应将筛选性强的条件放在 AND 的左侧或 OR 的左侧。AND 左侧为假时右侧不执行;OR 左侧为真时右侧不执行。这可以减少函数调用和复杂计算。

小结

  • AND 要求所有条件为真,OR 要求至少一个为真
  • 优先级:NOT > AND > OR,混用时务必加括号
  • IN 是多值 OR 的简洁写法
  • 短路求值意味着条件顺序可能影响性能
  • XOR 在实际业务中极少使用

下一章引子:条件判断中除了比较和逻辑,还经常需要对数据进行计算——算术运算符让查询中的数学运算成为可能。

上一页
比较运算符
下一页
算术运算符