MySQL: MySQL高级过滤与正则表达式查询

最后更新:2026-08-26

简单过滤不够用时,高级过滤让你精准定位数据。

本课深入讲解复杂条件组合和正则表达式。

100%
graph TB
    A[WHERE 条件组合] --> B[AND 逻辑与]
    A --> C[OR 逻辑或]
    A --> D[NOT 取反]
    B --> E[多条件同时满足]
    C --> F[满足任一条件]
    A --> G[IN 列表匹配]
    A --> H[BETWEEN 范围]
    A --> I[LIKE 通配符]
    A --> J[REGEXP 正则]
    A --> K[EXISTS 子查询]

1. 你将学到


2. 一个搜索功能的真实故事

(1) 痛点:搜索不精准

用户搜索 "john",要求匹配:

简单的 LIKE '%john%' 只能匹配一种情况。

(2) REGEXP 的解法

SQL
SELECT * FROM users 
WHERE first_name REGEXP '^john|john$|john' 
   OR email REGEXP 'john';

3. AND/OR 深入

▶ 示例:复杂条件组合

SQL
-- 查询:Engineering 或 Sales 部门,且工资 > 5000
SELECT * FROM employees 
WHERE (department = 'Engineering' OR department = 'Sales')
  AND salary > 5000;

-- 查询:工资 5000-8000,且不是 HR 部门
SELECT * FROM employees 
WHERE salary BETWEEN 5000 AND 8000
  AND department != 'HR';

-- 查询:入职 2024 年后,或工资 > 10000
SELECT * FROM employees 
WHERE hire_date >= '2024-01-01' OR salary > 10000;
▶ 试一试

4. IN/NOT IN

▶ 示例:列表查询

SQL
-- IN 查询
SELECT * FROM products WHERE category_id IN (1, 3, 5, 7);

-- NOT IN 查询
SELECT * FROM products WHERE category_id NOT IN (2, 4, 6);

-- 子查询 IN
SELECT * FROM employees 
WHERE department_id IN (SELECT id FROM departments WHERE location = 'Beijing');

-- NOT EXISTS 替代 NOT IN(性能更好)
SELECT * FROM customers c
WHERE NOT EXISTS (
    SELECT 1 FROM orders o WHERE o.customer_id = c.id
);
▶ 试一试

5. BETWEEN 进阶

▶ 示例:范围查询

SQL
-- 数值范围
SELECT * FROM products WHERE price BETWEEN 100 AND 500;

-- 日期范围
SELECT * FROM orders WHERE order_date BETWEEN '2026-01-01' AND '2026-06-30';

-- 字符串范围
SELECT * FROM employees WHERE last_name BETWEEN 'A' AND 'M';

-- NOT BETWEEN
SELECT * FROM products WHERE price NOT BETWEEN 100 AND 500;
▶ 试一试

6. LIKE 通配符

▶ 示例:模糊匹配

SQL
-- % 匹配任意多个字符(包括 0 个)
SELECT * FROM users WHERE name LIKE 'J%';        -- J 开头
SELECT * FROM users WHERE name LIKE '%son';      -- son 结尾
SELECT * FROM users WHERE name LIKE '%john%';    -- 包含 john

-- _ 匹配恰好一个字符
SELECT * FROM users WHERE name LIKE 'J_hn';      -- J_hn(John, Johan)

-- 组合使用
SELECT * FROM users WHERE email LIKE '%@gmail.com';

-- ESCAPE 转义特殊字符
SELECT * FROM files WHERE name LIKE '%\_%' ESCAPE '\\';  -- 包含 _
SELECT * FROM files WHERE name LIKE '%%' ESCAPE '\\';    -- 包含 %
▶ 试一试

7. REGEXP 正则表达式

(1) 常用正则元字符

元字符 说明 示例
^ 开头 '^John' — John 开头
$ 结尾 'son$' — son 结尾
. 任意单字符 'J.hn' — John, Johan
[...] 字符集 '[abc]' — a/b/c 之一
[^...] 排除字符集 [^abc] — 非 a/b/c
* 0 次或多次 'ab*' — a, ab, abb
+ 1 次或多次 'ab+' — ab, abb
? 0 次或 1 次 'ab?' — a, ab
{n} 恰好 n 次 'a{3}' — aaa
{n,m} n 到 m 次 'a{2,4}' — aa~aaaa
| 'cat|dog' — cat 或 dog

▶ 示例:REGEXP 查询

SQL
-- 以 J 或 j 开头
SELECT * FROM users WHERE first_name REGEXP '^[Jj]';

-- 包含数字
SELECT * FROM users WHERE username REGEXP '[0-9]';

-- 邮箱格式验证(简单)
SELECT * FROM users WHERE email REGEXP '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$';

-- 手机号格式(中国大陆)
SELECT * FROM users WHERE phone REGEXP '^1[3-9][0-9]{9}$';

-- 包含中文
SELECT * FROM users WHERE name REGEXP '[一-龥]';
▶ 试一试

▶ 示例:REGEXP vs LIKE

SQL
-- LIKE 只能前后匹配
SELECT * FROM users WHERE name LIKE '%john%';  -- 包含 john

-- REGEXP 可以精确控制
SELECT * FROM users WHERE name REGEXP '^john$'; -- 完全等于 john(不区分大小写)
SELECT * FROM users WHERE name REGEXP 'john|jane'; -- john 或 jane
SELECT * FROM users WHERE name REGEXP '^[A-Z]'; -- 大写字母开头
▶ 试一试

8. EXISTS 子查询

▶ 示例:EXISTS 用法

SQL
-- 查询有订单的客户
SELECT * FROM customers c
WHERE EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.id);

-- 查询没有订单的客户
SELECT * FROM customers c
WHERE NOT EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.id);
▶ 试一试

❓ 常见问题

Q LIKE '%keyword%' 能走索引吗?
A 前缀有 % 无法走索引,会全表扫描。大数据量考虑全文索引(FULLTEXT)。
Q REGEXP 和 LIKE 哪个快?
A 通常 LIKE 更快(可以走索引)。REGEXP 更灵活但不能走索引(MySQL 8.0 部分支持)。
Q IN 和 OR 哪个性能好?
A 数据少时差不多。IN 列表很长时,MySQL 会优化为排序后二分查找,比 OR 快。
Q NOT IN 有 NULL 陷阱?
A 是的。NOT IN (1, 2, NULL) 永远返回空,因为 NULL 参与比较结果为 NULL。用 NOT EXISTS 替代。

📖 小节


📝 作业

  1. 基础题(难度⭐):用 LIKE 查询邮箱包含 '@gmail.com' 且用户名以 'J' 开头的用户。

  2. 进阶题(难度⭐⭐):用 REGEXP 查询中国大陆手机号(1 开头,第二位 3-9,共 11 位)。

  3. 挑战题(难度⭐⭐⭐):对比 NOT IN 和 NOT EXISTS 在包含 NULL 值时的查询结果差异。

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏