第7章 数据过滤
一、核心概念
- AND操作符
作用:同时满足多个条件语法示例:WHERE cond1 AND cond2优先级:高于OR
2. OR操作符
作用:至少满足一个条件语法示例:WHERE cond1 OR cond2注意:必须用括号包裹多条件
3. IN操作符
作用:指定值列表匹配对比优势:比连续OR更简洁高效语法示例:WHERE col IN (val1, val2)
4. NOT操作符
作用:反向选择不符合条件的行典型应用:排除特定值语法示例:WHERE NOT col = val1
二、执行优先级
运算顺序从高到低:
- 括号()
- AND
- OR # 需要特别注意优先级规则
三、实战演练
① 建表语句
-- 创建产品表
CREATE TABLE products (
prod_id INT PRIMARY KEY, -- 产品ID,作为主键
prod_name VARCHAR(255) NOT NULL, -- 产品名称,不允许为空
prod_price DECIMAL(10,2) NOT NULL,-- 产品价格,十位整数两位小数,不允许为空
vend_id INT NOT NULL -- 供应商ID,不允许为空
);
-- 向产品表中插入数据
INSERT INTO products VALUES
(1, 'Hammer', 15.99, 1001), -- 锤子
(2, 'Screwdriver', 8.50, 1002), -- 螺丝刀
(3, 'Wrench', 12.75, 1001), -- 扳手
(4, 'Pliers', 9.99, 1003), -- 钳子
(5, 'Drill', 89.99, 1001), -- 电钻
(6, 'Level', 24.95, 1002), -- 水平尺
(7, 'Tape Measure', 7.45, 1003); -- 卷尺
② 练习题集合
题目1:AND条件
-- 查找供应商ID=1001且售价超过15元的工具
SELECT *
FROM products
WHERE vend_id = 1001 AND prod_price > 15;
/* 预期结果
+---------+-----------+------------+---------+
| prod_id | prod_name | prod_price | vend_id |
+---------+-----------+------------+---------+
| 5 | Drill | 89.99 | 1001 |
+---------+-----------+------------+---------+ */
题目2:OR条件优先
-- 查找供应商1001或1002生产,且售价<=10元的工具
SELECT *
FROM products
WHERE (vend_id = 1001 OR vend_id = 1002)
AND prod_price <= 10;
/* 预期结果
+---------+-------------+------------+---------+
| prod_id | prod_name | prod_price | vend_id |
+---------+-------------+------------+---------+
| 2 | Screwdriver | 8.50 | 1002 |
+---------+-------------+------------+---------+ */
题目3:IN替代OR
-- 查找价格是8.50、12.75或24.95的商品
SELECT *
FROM products
WHERE prod_price IN (8.50, 12.75, 24.95);
/* 预期结果
+---------+-------------+------------+---------+
| prod_id | prod_name | prod_price | vend_id |
+---------+-------------+------------+---------+
| 2 | Screwdriver | 8.50 | 1002 |
| 3 | Wrench | 12.75 | 1001 |
| 6 | Level | 24.95 | 1002 |
+---------+-------------+------------+---------+ */
题目4:NOT排除
-- 列出供应商ID非1003的产品
SELECT *
FROM products
WHERE NOT vend_id = 1003;
/* 预期结果
+---------+-------------+------------+---------+
| prod_id | prod_name | prod_price | vend_id |
+---------+-------------+------------+---------+
| 1 | Hammer | 15.99 | 1001 |
| 2 | Screwdriver | 8.50 | 1002 |
| 3 | Wrench | 12.75 | 1001 |
| 5 | Drill | 89.99 | 1001 |
| 6 | Level | 24.95 | 1002 |
+---------+-------------+------------+---------+ */
四、学习要点
AND/OR组合必须用括号明确优先级IN在值较多时代码更简洁NOT适合需要反向过滤的场景复杂条件建议分步验证
第8章 用通配符进行过滤
核心知识
通配符的作用
用于匹配文本片段(代替具体字符),常配合LIKE操作符使用,适合部分模糊搜索场景。
两个核心通配符
- %:匹配任意多个字符(包括0次)
- _:匹配单个字符
示例:
a%匹配以"a"开头的字符串,%net%匹配包含"net"的任意位置。
LIKE语法
SELECT 列名 FROM 表名 WHERE 列名 LIKE '通配符模式';[1](@ref)
注意事项
- 默认不区分大小写(可通过配置调整)
- 通配符在前可能无法使用索引,导致全表扫描
- 避免过度使用(优先考虑全文检索等高效方案)
实战演练:产品搜索系统
步骤1:创建表并插入数据
-- 创建产品表[2](@ref)
CREATE TABLE products (
prod_id INT AUTO_INCREMENT PRIMARY KEY,
prod_name VARCHAR(50) NOT NULL,
prod_price DECIMAL(10,2) NOT NULL
);
-- 插入测试数据
INSERT INTO products (prod_name, prod_price)
VALUES
('2 ton Anvil', 9.99),
('TNT (1 stick)', 2.99),
('Oil Can', 10.00),
('Fuses', 1.49),
('Bird seed', 5.00),
('Carrots', 0.99);
步骤2:编写查询题目
1. 题目1:查找名称中包含anvil的产品
SELECT * FROM products
WHERE prod_name LIKE '%anvil%';
-- 结果:2 ton Anvil
2. 题目2:查找价格低于$10且名称以T开头的产品
SELECT * FROM products
WHERE prod_name LIKE 'T%'
AND prod_price < 10;
-- 结果:TNT (1 stick)
3. 题目3:查找名称第2字符是o且总长>=5字符的产品
SELECT * FROM products
WHERE prod_name LIKE '_o%';
-- 结果:Oil Can
高频易错点
- 通配符位置陷阱
LIKE '%abc'需匹配以"abc"结尾的字符串,但尾部空格的存储可能影响结果(如"abc "会不匹配)。 - 区分大小写场景
若需区分大小写,需检查数据库的字符集和校对规则设置。 - 性能优化
对频繁使用的模糊查询,可考虑:
- 增加前缀索引(如INDEX (prod_name(5)))
- 使用全文索引(对大型文本更高效)
第9章 用正则表达式进行搜索
一、正则表达式介绍
正则表达式是用来匹配文本的特殊串(字符集合),可用于从文本中提取特定信息,如电话号码、特定格式的文件名等。它使用正则表达式语言建立,具有特殊语法和指令。虽然 MySQL 仅支持多数正则表达式实现的一个小子集,但在数据过滤方面仍很有用。
二、使用 MySQL 正则表达式
(一) 基本字符匹配
- 使用REGEXP关键字在WHERE子句中进行正则表达式匹配。它与LIKE的重要区别在于,LIKE匹配整个列,而REGEXP在列值内进行匹配。例如,SELECT prod_name FROM products WHERE prod_name REGEXP '1000'能检索出列值中包含1000的行,而SELECT prod_name FROM products WHERE prod_name LIKE '1000'若不用通配符则无法检索到相关行。
(二) 进行 OR 匹配
- 使用|操作符实现 OR 匹配,如SELECT prod_name FROM products WHERE prod_name REGEXP '1000|2000'可检索出列值中包含1000或2000的行。
(三) 匹配几个字符之一
- 通过指定一组用[和]括起来的字符来匹配特定字符,如[123]Ton表示匹配1Ton、2Ton或3Ton。字符集合也可被否定,在集合开始处放置^,如[^123]匹配除1、2、3外的任何字符 。
(四) 匹配范围
- 用-定义范围,如[0 - 9]匹配数字0到9,[1 - 3]匹配1到3,[a - z]匹配任意字母字符。例如,SELECT prod_name FROM products WHERE prod_name REGEXP '[1 - 5]Ton'可检索出产品名中包含1Ton到5Ton的行。
(五) 匹配特殊字符
- 为匹配正则表达式中的特殊字符,如.、|、[]等,必须用\为前导进行转义,如\1.表示查找.。\\还用于引用元字符,如\f(换页)、\n(换行)等。
(六) 匹配字符类
- MySQL 提供了预定义的字符集,即字符类,如[:alnum:]表示任意字母和数字,[:digit:]表示任意数字等。使用字符类可更方便地进行匹配,如SELECT prod_name FROM products WHERE prod_name REGEXP '[[:digit:]]{4}'可检索出产品名中包含连在一起的 4 位数字的行。
(七) 匹配多个实例
- 通过重复元字符对匹配数目进行控制,如*表示 0 个或多个匹配,+表示 1 个或多个匹配,?表示 0 个或 1 个匹配,{n}表示指定数目的匹配,{n,}表示不少于指定数目的匹配,{n,m}表示匹配数目的范围(m不超过 255) 。例如,SELECT prod_name FROM products WHERE prod_name REGEXP '([0 - 9]sticks?)'可检索出产品名中包含数字 + sticks或数字 + stick的行。
(八) 定位符
- 使用定位符匹配特定位置的文本,如^匹配文本的开始,$匹配文本的结尾,[[:<:]]匹配词的开始,[[:>:]]匹配词的结尾。例如,SELECT prod_name FROM products WHERE prod_name REGEXP '^[0 - 9\\.]'可检索出以数字或小数点开始的产品名的行。利用定位符,通过用^开始每个表达式,用$结束每个表达式,可使REGEXP的作用与LIKE一样匹配整个串。
三、小结
本章介绍了正则表达式的基础知识,以及如何在 MySQL 的SELECT语句中通过REGEXP关键字使用它们。简单的正则表达式测试可在不使用数据库表的情况下用SELECT来测试,REGEXP检查总是返回0(没有匹配)或1(匹配)。
四、实战案例
(一) 实战数据准备
1. 建表语句
CREATE TABLE test_regex (
id INT AUTO_INCREMENT PRIMARY KEY,
content VARCHAR(255) NOT NULL
);
2. 插入数据语句
INSERT INTO test_regex (content) VALUES ('abc123'), ('def456'), ('789ghi'), ('abcdef'), ('123abc');
(二) 题目
1. 检索content列中包含数字的行。
利用正则表达式匹配包含数字的行,可使用[0 - 9]表示任意数字。
SELECT * FROM test_regex WHERE content REGEXP '[0 - 9]';
2. 检索content列中以字母开头,后面跟着 3 个数字的行。
使用定位符^匹配文本开始,[a - zA - Z]匹配任意字母,{3}表示前面字符出现 3 次。
SELECT * FROM test_regex WHERE content REGEXP '^[a - zA - Z][0 - 9]{3}';
3. 检索content列中包含abc或def的行。
使用|操作符实现 OR 匹配。
SELECT * FROM test_regex WHERE content REGEXP 'abc|def';