MySQL 逻辑运算符

🎉摘要:本文详细讲解MySQL中AND、OR、NOT逻辑运算符的用法、真值表、NULL处理及优先级规则,通过示例演示如何组合复杂条件进行数据过滤,并给出避免多层取反和强制括号的建议。

前面介绍了在 where 语句中使用比较运算符、范围查询(between)、集合查询(in)、空值判断(is null)和模糊查询(like)实现数据过滤。

下面将介绍使用 AND、OR 和 NOT 将多个条件进行组合,实现更为复杂的过滤条件:

AND(与)

AND 是逻辑与运算符,用于拼接两个及以上查询条件。只有所有条件同时成立时,整行数据才会被筛选出来。任意一个条件不满足,该行都会被过滤。主要用在 WHERE、HAVING、CASE WHEN等需要条件判断的场景。

语法格式:条件A AND 条件B

条件 A 结果条件 B 结果AND 最终结果
成立(真)成立(真)✅️成立
成立(真)不成立(假)不成立
不成立(假)成立(真)不成立
不成立(假)不成立(假)不成立

简单示例:

-- 查询年龄等于22,用户姓名以“zheng”开头的用户信息
mysql> select * from users where user_age=22 and username like 'zheng%';
+---------+-------------+----------+---------------------+-------------+---------------------+
| user_id | username    | user_age | email               | phone       | created_at          |
+---------+-------------+----------+---------------------+-------------+---------------------+
|       9 | zheng_shiyi |       22 | zheng11@example.com | 13800138009 | 2026-07-29 13:55:25 |
+---------+-------------+----------+---------------------+-------------+---------------------+
1 row in set (0.00 sec)

  

OR(或)

OR 是逻辑或运算符,用于拼接多个查询条件,任意一个条件成立,整条判定结果即为成立,只要满足其中一项数据就会被筛选出来。主要用于 WHERE、HAVING、CASE WHEN 等需要多条件择一匹配的场景。

语法格式:条件1 OR 条件2 OR 条件3 ...

条件 A条件 BA OR B 最终结果
✅️真
✅️真
✅️真

简单示例:

-- 查询年龄等于50、或用户姓名以“zheng”开头的用户信息
mysql> select * from users where user_age=50 or username like 'zheng%';
+---------+-------------+----------+---------------------+-------------+---------------------+
| user_id | username    | user_age | email               | phone       | created_at          |
+---------+-------------+----------+---------------------+-------------+---------------------+
|       8 | wu_shi      |       50 | wushi@example.com   | 13800138008 | 2026-07-29 13:55:25 |
|       9 | zheng_shiyi |       22 | zheng11@example.com | 13800138009 | 2026-07-29 13:55:25 |
+---------+-------------+----------+---------------------+-------------+---------------------+
2 rows in set (0.00 sec)

mysql 广告位

NOT(非)

NOT 意为取反、非,对紧随其后的查询条件进行真假翻转:

  • 条件成立 → 使用NOT后不成立

  • 条件不成立 → 使用NOT后成立

NOT 常搭配 WHERE、HAVING、CASE WHEN 等场景做条件反转。

运算优先级:NOT 优先级高于 AND、OR,执行顺序:NOT > AND > OR

多条件混杂时建议用小括号限定判断范围,避免逻辑错乱。

语法格式:NOT 条件

简单示例:

-- 查询用户名不以“z”开头的用户信息
mysql> select * from users where username not like 'z%';
+---------+------------+----------+--------------------+-------------+---------------------+
| user_id | username   | user_age | email              | phone       | created_at          |
+---------+------------+----------+--------------------+-------------+---------------------+
|       2 | li_si      |       28 | lisi@example.com   | 13800138002 | 2026-07-29 13:55:25 |
|       3 | wang_wu    |       35 | wangwu@example.com | 13800138003 | 2026-07-29 13:55:25 |
|       5 | qian_qi    |       42 | qianqi@example.com | 13800138005 | 2026-07-29 13:55:25 |
|       6 | sun_ba     |       26 | sunba@example.com  | 13800138006 | 2026-07-29 13:55:25 |
|       8 | wu_shi     |       50 | wushi@example.com  | 13800138008 | 2026-07-29 13:55:25 |
|      10 | chen_shier |       38 | chen12@example.com | 13800138010 | 2026-07-29 13:55:25 |
+---------+------------+----------+--------------------+-------------+---------------------+
6 rows in set (0.00 sec)

注意,NOT 语句存在几个关键特性与避坑要点,使用时要谨慎:

(1)NULL 参与 NOT 运算依旧为 NULL

NULL 代表未知值,NOT NULL结果依旧是未知,不会判定为真 / 假。例如:

-- 无效写法,查不出任何数据
mysql> select * from users where not user_age = null;
Empty set (0.00 sec)

-- 正确写法
mysql> select * from users where not user_age is null;
+---------+-------------+----------+----------------------+-------------+---------------------+
| user_id | username    | user_age | email                | phone       | created_at          |
+---------+-------------+----------+----------------------+-------------+---------------------+
|       1 | zhang_san   |       23 | zhangsan@example.com | 13800138001 | 2026-07-29 13:55:25 |
|       2 | li_si       |       28 | lisi@example.com     | 13800138002 | 2026-07-29 13:55:25 |
|       3 | wang_wu     |       35 | wangwu@example.com   | 13800138003 | 2026-07-29 13:55:25 |
|       4 | zhao_liu    |       19 | zhaoliu@example.com  | NULL        | 2026-07-29 13:55:25 |
|       5 | qian_qi     |       42 | qianqi@example.com   | 13800138005 | 2026-07-29 13:55:25 |
|       6 | sun_ba      |       26 | sunba@example.com    | 13800138006 | 2026-07-29 13:55:25 |
|       7 | zhou_jiu    |       31 | zhoujiu@example.com  | NULL        | 2026-07-29 13:55:25 |
|       8 | wu_shi      |       50 | wushi@example.com    | 13800138008 | 2026-07-29 13:55:25 |
|       9 | zheng_shiyi |       22 | zheng11@example.com  | 13800138009 | 2026-07-29 13:55:25 |
|      10 | chen_shier  |       38 | chen12@example.com   | 13800138010 | 2026-07-29 13:55:25 |
+---------+-------------+----------+----------------------+-------------+---------------------+
10 rows in set (0.00 sec)

(2)尽量少用嵌套多层 NOT

多层取反会大幅降低 SQL 可读性,能正向判断优先正向书写。例如:

-- 不推荐:双重取反绕逻辑
mysql> select * from users where not not user_age >= 35;
+---------+------------+----------+--------------------+-------------+---------------------+
| user_id | username   | user_age | email              | phone       | created_at          |
+---------+------------+----------+--------------------+-------------+---------------------+
|       3 | wang_wu    |       35 | wangwu@example.com | 13800138003 | 2026-07-29 13:55:25 |
|       5 | qian_qi    |       42 | qianqi@example.com | 13800138005 | 2026-07-29 13:55:25 |
|       8 | wu_shi     |       50 | wushi@example.com  | 13800138008 | 2026-07-29 13:55:25 |
|      10 | chen_shier |       38 | chen12@example.com | 13800138010 | 2026-07-29 13:55:25 |
+---------+------------+----------+--------------------+-------------+---------------------+
4 rows in set (0.00 sec)

-- 推荐直接正向判断
mysql> select * from users where not not user_age >= 35;

(3)NOT 与 !=、<> 的选用区别

  • NOT 字段=值”语义上等价于 “字段!=值”、“字段<>值

  • 简单不等判断优先用 !=

  • 需要对区间、集合、模糊查询、整组条件取反时,只能用 NOT

(4)结合逻辑优先级示例

-- 不加括号:先执行 not user_age=50,再执行 and user_age>35
mysql> select * from users where not user_age=50 and user_age>35;
+---------+------------+----------+--------------------+-------------+---------------------+
| user_id | username   | user_age | email              | phone       | created_at          |
+---------+------------+----------+--------------------+-------------+---------------------+
|       5 | qian_qi    |       42 | qianqi@example.com | 13800138005 | 2026-07-29 13:55:25 |
|      10 | chen_shier |       38 | chen12@example.com | 13800138010 | 2026-07-29 13:55:25 |
+---------+------------+----------+--------------------+-------------+---------------------+
2 rows in set (0.00 sec)

-- 加括号:整体对 user_age=50 and user_age>35 取反
mysql> select * from users where not (user_age=50 and user_age>35);
+---------+-------------+----------+----------------------+-------------+---------------------+
| user_id | username    | user_age | email                | phone       | created_at          |
+---------+-------------+----------+----------------------+-------------+---------------------+
|       1 | zhang_san   |       23 | zhangsan@example.com | 13800138001 | 2026-07-29 13:55:25 |
|       2 | li_si       |       28 | lisi@example.com     | 13800138002 | 2026-07-29 13:55:25 |
|       3 | wang_wu     |       35 | wangwu@example.com   | 13800138003 | 2026-07-29 13:55:25 |
|       4 | zhao_liu    |       19 | zhaoliu@example.com  | NULL        | 2026-07-29 13:55:25 |
|       5 | qian_qi     |       42 | qianqi@example.com   | 13800138005 | 2026-07-29 13:55:25 |
|       6 | sun_ba      |       26 | sunba@example.com    | 13800138006 | 2026-07-29 13:55:25 |
|       7 | zhou_jiu    |       31 | zhoujiu@example.com  | NULL        | 2026-07-29 13:55:25 |
|       9 | zheng_shiyi |       22 | zheng11@example.com  | 13800138009 | 2026-07-29 13:55:25 |
|      10 | chen_shier  |       38 | chen12@example.com   | 13800138010 | 2026-07-29 13:55:25 |
+---------+-------------+----------+----------------------+-------------+---------------------+
9 rows in set (0.00 sec)

两句执行逻辑完全不同,复杂条件务必加括号约束范围。

运算符优先级

逻辑运算符的优先级:NOT > AND > OR

-- 这个查询的逻辑是:查询年龄大于30且用户名以wu开头的用户信息,和用户名以zhang开头的用户信息
mysql> select * from users where user_age>30 and username like 'wu%' or username like 'zhang%';
+---------+-----------+----------+----------------------+-------------+---------------------+
| user_id | username  | user_age | email                | phone       | created_at          |
+---------+-----------+----------+----------------------+-------------+---------------------+
|       1 | zhang_san |       23 | zhangsan@example.com | 13800138001 | 2026-07-29 13:55:25 |
|       8 | wu_shi    |       50 | wushi@example.com    | 13800138008 | 2026-07-29 13:55:25 |
+---------+-----------+----------+----------------------+-------------+---------------------+
2 rows in set (0.00 sec)

-- 为了避免混淆,建议用括号明确优先级
mysql> select * from users where (user_age>30 and username like 'wu%') or username like 'zhang%';
+---------+-----------+----------+----------------------+-------------+---------------------+
| user_id | username  | user_age | email                | phone       | created_at          |
+---------+-----------+----------+----------------------+-------------+---------------------+
|       1 | zhang_san |       23 | zhangsan@example.com | 13800138001 | 2026-07-29 13:55:25 |
|       8 | wu_shi    |       50 | wushi@example.com    | 13800138008 | 2026-07-29 13:55:25 |
+---------+-----------+----------+----------------------+-------------+---------------------+
2 rows in set (0.00 sec)

注意,为了避免混淆建议添加括号明确优先级。

  

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号