在MySQL查询中,BETWEEN用于选取某个闭区间内的数据,LIKE则负责按模式进行模糊匹配。把这两个条件组合使用,可以同时满足范围限定与关键字过滤的需求,但要注意数据类型、边界包含以及索引使用情况。

一、BETWEEN条件的基础用法
BETWEEN后面跟两个值,表示字段值大于等于第一个值,并且小于等于第二个值。它是一个闭区间,这一点和某些编程语言里的开区间函数不同,初学者经常误以为不包含边界。
下面以订单表为例,查询2023年1月1日到2023年1月31日之间的订单。注意BETWEEN对日期类型同样适用,但需要确保日期格式正确,或者用字符串的字典序比较。如果字段是DATETIME类型,BETWEEN '2023-01-01' AND '2023-01-31'只会取到1月31日零点,不包含当天后续时间。
-- 查询指定日期范围内的订单id和金额 SELECT order_id, amount FROM orders WHERE order_date BETWEEN '2023-01-01' AND '2023-01-31';
如果希望包含1月31日全天,应该把上限写成次日的零点,或者使用大于等于和小于的组合。这种写法在涉及时间字段时更加安全,也能让优化器更清楚地知道范围。
-- 更严谨的日期范围写法 SELECT order_id, amount FROM orders WHERE order_date >= '2023-01-01' AND order_date < '2023-02-01';
二、LIKE条件与通配符
LIKE用来做字符串的模糊查询,它支持两个主要通配符:百分号%代表任意长度字符,下划线_代表单个字符。例如'张%'匹配所有以张开头的姓名,而'张_'只匹配张后面跟一个字的两字姓名。
当百分号出现在最左侧,如'%手机',MySQL通常无法使用该列上的普通索引,会进行全表扫描。如果业务允许,尽量把确定前缀放在前面,或者考虑全文索引来提升性能。
-- 查找姓名以张开头的用户 SELECT user_id, user_name FROM users WHERE user_name LIKE '张%'; -- 查找姓名中包含手机二字的用户 SELECT user_id, user_name FROM users WHERE user_name LIKE '%手机%';
有时我们要搜索本身带有百分号或下划线的内容,这时需要用ESCAPE定义转义符。比如商品名里真的有下划线,可以用LIKE 'A_B' ESCAPE ''来精确匹配。
-- 转义下划线,匹配名称为 A_B 的商品 SELECT product_id, product_name FROM products WHERE product_name LIKE 'A_B' ESCAPE '';
三、BETWEEN与LIKE同时使用的写法
在同一个WHERE子句中,BETWEEN和LIKE可以通过AND或OR连接。最常见的场景是:先限定时间范围,再在范围内做名称模糊搜索。这种组合不会相互冲突,只是各自独立发挥作用。
以下语句查询2023年第一季度下单、且客户名包含科技二字的所有记录。BETWEEN负责时间闭区间,LIKE负责模糊过滤,两者通过AND同时生效。
-- 时间区间 + 名称模糊匹配 SELECT order_id, customer_name, order_date FROM orders WHERE order_date BETWEEN '2023-01-01' AND '2023-03-31' AND customer_name LIKE '%科技%';
如果想查找不在某区间或不符合模式的记录,可以配合NOT使用。但要注意NOT LIKE和NOT BETWEEN都会让索引使用变得复杂,数据量大时建议先用EXPLAIN分析执行计划。
-- 排除特定区间和特定名称前缀 SELECT order_id, customer_name FROM orders WHERE order_date NOT BETWEEN '2023-01-01' AND '2023-03-31' AND customer_name NOT LIKE '测试%';
四、数据类型与性能注意点
BETWEEN对数值、日期、字符串都有效,但字符串比较依据字符集和排序规则。例如在区分大小写的校对规则下,'abc' BETWEEN 'AAA' AND 'ABD'的结果和默认规则可能不同。写区间时务必保证两端类型与字段一致,避免隐式转换导致索引失效。
从性能角度看,BETWEEN在索引列上通常能命中range扫描,效率较高;LIKE只有非前导通配符时才能利用索引。如果业务高频使用两者组合,可以考虑在where条件顺序上把能走索引的BETWEEN放在前面,虽然MySQL优化器会重排,但清晰的语句更利于维护。
| 条件组合 | 索引使用情况 | 适用场景 |
|---|---|---|
| BETWEEN 索引列 | 走range索引 | 时间、数值范围查询 |
| LIKE '前缀%' | 走range索引 | 已知开头模糊搜 |
| LIKE '%关键词' | 全表扫描 | 低频或短表查询 |
| BETWEEN + LIKE AND | 取决于优化器与列顺序 | 范围加过滤综合查询 |
实际开发中,建议把这类查询封装成存储过程或持久层方法,并加上EXPLAIN检查。当数据量达到百万级,单纯依赖BETWEEN和LIKE可能不够,需要结合分区表或搜索引擎来分担压力。
五、常见错误与纠正
一个典型错误是把BETWEEN写成column BETWEEN '2023-01-31' AND '2023-01-01',也就是小值放在后面。MySQL不会自动交换顺序,这样会返回空结果。必须保证第一个值小于等于第二个值。
另一个错误是在LIKE里拼接用户输入时不处理转义,导致用户输入下划线匹配了任意单字。应在程序层对用户输入中的%、_做转义处理,再拼入SQL,或者使用预编译参数绑定来避免意外通配。
// PHP中对用户输入做LIKE转义示例 $raw = $_GET['kw']; $escaped = addcslashes($raw, '%_'); $sql = "SELECT * FROM articles WHERE title LIKE '%" . $escaped . "%'";
通过理解闭区间本质、通配符规则以及索引行为,就能在MySQL中稳妥地使用BETWEEN和LIKE条件,写出结果准确且易于优化的查询语句。