高级过滤
多条件组合、IN与NOT、LIKE模糊匹配、正则搜索
AND 与 OR:组合多个条件
上一章的 WHERE 一次只筛一个条件。现实中往往是"查北京且工资大于 8000 的人"——多个条件组合。
AND
所有条件同时成立:
SELECT name, city, salary
FROM users
WHERE city = '北京' AND salary > 7000;+--------+--------+----------+
| name | city | salary |
+--------+--------+----------+
| 张三 | 北京 | 8000.00 |
| 郑十 | 北京 | 7800.00 |
+--------+--------+----------+孙七是北京的但工资 6000,被筛掉了。AND 可以串联多个:
WHERE city = '北京' AND salary > 7000 AND age < 30;OR
任一条件成立即可:
SELECT name, city, salary
FROM users
WHERE city = '北京' OR city = '上海';北京和上海的所有员工都出来了。
AND 和 OR 混用时的坑
看这个查询——想查"北京或上海,且工资大于 10000 的人":
-- ❌ 这样写有问题
SELECT name, city, salary
FROM users
WHERE city = '北京' OR city = '上海' AND salary > 10000;结果可能和你预期不一样。原因是 AND 优先级比 OR 高,MySQL 会先算 city = '上海' AND salary > 10000,再把结果和 city = '北京' 做 OR。
所有北京的人都会出来(不管工资多少),而上海只出工资大于 10000 的。
✅ 加括号明确意图:
SELECT name, city, salary
FROM users
WHERE (city = '北京' OR city = '上海') AND salary > 10000;+--------+--------+----------+
| name | city | salary |
+--------+--------+----------+
| 李四 | 上海 | 12000.00 |
| 周八 | 上海 | 11000.00 |
+--------+--------+----------+这次对了:北京和上海中,工资大于 10000 的才出现。
📝 经验法则:只要 AND 和 OR 混用,一律加括号,省得背优先级表,也省得别人看懵。
IN:一次匹配多个值
想查北京、上海、广州三地的人,用 OR 得写三次:
WHERE city = '北京' OR city = '上海' OR city = '广州';用 IN 简洁得多:
SELECT name, city FROM users
WHERE city IN ('北京', '上海', '广州');括号里列什么,就匹配什么。IN 的好处:
- 写法干净——三个值还行,十个值用 OR 会写到崩溃
- 可以和 NOT 搭配——
NOT IN (...)表示"不含这些" - 里面可以放子查询(后面会讲)
NOT:取反
NOT 的意思就是"不是"。常和 IN、BETWEEN 搭配:
-- 不在北京、上海、广州的
SELECT name, city FROM users
WHERE city NOT IN ('北京', '上海', '广州');
-- 工资不在 8000-12000 之间的
SELECT name, salary FROM users
WHERE salary NOT BETWEEN 8000 AND 12000;单独用也行(但不常见):
SELECT name FROM users WHERE NOT city = '北京';
-- 等价于 WHERE city <> '北京'LIKE:模糊匹配
前面都是精确匹配——city = '北京',一个字不能差。但实际场景常是"搜姓张的人"、"找名称里含'科技'的公司"——这是模糊匹配。
% 通配符:匹配任意多个字符
-- 姓张的人
SELECT name FROM users WHERE name LIKE '张%';张% 的意思是"张开头,后面随便"。结果:张三。
-- 名字里有"八"的人
SELECT name FROM users WHERE name LIKE '%八%';%八% 的意思是"前后随便,中间有'八'"。结果:周八。
-- 以"州"结尾的城市
SELECT city FROM users WHERE city LIKE '%州';结果:广州、杭州。
_ 通配符:只匹配单个字符
-- 姓"某"的单名(总计两个字)
SELECT name FROM users WHERE name LIKE '_某';_ 一个下划线只匹配一个字符。两个下划线匹配两个,以此类推。
通配符的使用技巧
- 不要放在开头用——
LIKE '%张'会导致索引失效,查询变慢 - 能不用就不用——精确匹配永远比模糊匹配快
- 注意尾随空格——
LIKE '张%'不会匹配' 张'前面有空格的情况
REGEXP:正则表达式搜索
LIKE 能做的事有限。比如"找出名字由两个汉字组成的人",LIKE 办不到。这时候上 REGEXP:
-- 名字恰好两个字
SELECT name FROM users WHERE name REGEXP '^..$';基本字符匹配
-- 包含"八"
SELECT name FROM users WHERE name REGEXP '八';这和 LIKE '%八%' 一样。
OR 匹配
-- 包含"三"或"四"
SELECT name FROM users WHERE name REGEXP '三|四';字符类
| 类 | 说明 |
|---|---|
[0-9] | 任意数字 |
[a-z] | 任意小写字母 |
[A-Z] | 任意大写字母 |
-- 城市名包含字母(这里 city 都是中文,仅供示例)
SELECT city FROM users WHERE city REGEXP '[a-z]';定位符
| 符号 | 说明 |
|---|---|
^ | 开头 |
$ | 结尾 |
LIKE vs REGEXP
| LIKE | REGEXP |
|---|---|
| 匹配整列 | 匹配列内子串 |
LIKE '张%' 匹配以"张"开头 | REGEXP '张' 匹配任意位置有"张" |
| 简单场景 | 复杂模式 |
💡 日常用
LIKE就够了,需要复杂匹配时再上REGEXP。
小结
过滤升级了——从单个条件变成了组合拳:
- AND 和 OR 一起用时加括号 — 优先级问题是最常见的坑,不确定就加括号
- IN 替代多个 OR —
city IN ('北京','上海')比city='北京' OR city='上海'简洁 - NOT 取反 — 配合 IN / LIKE 用最顺手
- LIKE 模糊匹配 —
%通配任意字符,_通配单个字符,简单场景首选 - REGEXP 是进阶武器 — 知道有就行,需要复杂模式时再翻回来查
自主练习
- 查北京且年龄小于 28 的员工
- 查深圳或杭州,且工资大于 10000 的人(注意括号)
- 查名字以"张"或"李"开头的人(用 REGEXP 的
|) - 查不在北京、上海、广州的人
- 查名字恰好两个字的员工