☰
SQL年龄区间:BETWEEN包含两端,为什么换成OR就筛错了?
2026/10/6 1:50:47 网站建设 项目流程

牛客 SQL8要求查询 20 岁及以上、23 岁及以下的用户,返回设备 ID、性别、年龄。

原题要求的是闭区间,两端都包含:

SELECT device_id, gender, age FROM user_profile WHERE age >= 20 AND age <= 23;

原稿用 && 连接带引号的数字。在 MySQL 原环境中不必然错,这次改用标准 AND 和数值常量,让条件更清楚。本篇接着单个年龄边界,重点看“两个边界怎样围成一个范围”。

1. 两个条件是取交集,不是取并集

至少20岁: 20 ------------------> 最多23岁: <------------------ 23 同时满足: 20 ======== 23

如果换成 OR,只要满足一个条件就能进入。19 岁满足“不超过 23”,24 岁满足“不低于 20”,两个本来应该排除的年龄都被收进来了。对于已知数值,age >= 20 OR age <= 23 覆盖整个数轴,不是年龄段。

2. BETWEEN 是含两端的简写

对本题数值类型一致的年龄与常量,可以写成:

SELECT device_id, gender, age FROM user_profile WHERE age BETWEEN 20 AND 23;

20 和 23 都会被包含。这里的 AND 属于 BETWEEN 语法,不是要把 BETWEEN 20 当成独立条件。MySQL BETWEEN 说明。

不能把 BETWEEN 23 AND 20 理解为数据库自动交换上下限。若接口传来两个边界,应该先验证顺序,必要时按业务规则规范化,而不是期待 SQL 猜意图。

3. 放齐端点内外的数据再比较

在自己的练习数据库建立独立表,表名存在时换名:

CREATE TABLE sql8_range_demo ( device_id INT NOT NULL PRIMARY KEY, gender VARCHAR(14) NOT NULL, age INT ); INSERT INTO sql8_range_demo VALUES (1,'male',19),(2,'male',20),(3,'female',21), (4,'female',23),(5,'male',24),(6,'male',NULL);
SELECT device_id, gender, age FROM sql8_range_demo WHERE age BETWEEN 20 AND 23 ORDER BY device_id;
device_idgenderage
2male20
3female21
4female23

加 ORDER BY 只是让实验输出便于核对,不表示 BETWEEN 会自动排序。

可以把几种条件一次取出来对照:

SELECT device_id, age, (age >= 20 AND age <= 23) AS closed_range, (age BETWEEN 20 AND 23) AS between_range, (age >= 20 OR age <= 23) AS wrong_union FROM sql8_range_demo ORDER BY device_id;
ageclosed_rangebetween_rangewrong_union
19001
20111
21111
23111
24001
NULLNULLNULLNULL

NULL 不是 0 岁。区间比较结果未知,WHERE 不保留它,不能由没有出现在结果里推断这个用户年龄一定在范围之外。

4. 同一个写法,不能机械照搬到时间筛选

如果年龄需求改为“大于 20,且小于 23”,就应该改成 > 与 <,不是继续沿用含两端的 BETWEEN。

时间字段还有另一个常见问题:“查某一天”不是“查某天零点到某天零点”。下面用独立名字 logs_demo 作 SQL 示意,假设它有 created_at 时间列,未提供该表就不能直接执行:

SELECT created_at FROM logs_demo WHERE created_at >= '2026-10-05 00:00:00' AND created_at < '2026-10-06 00:00:00';

这是左闭右开区间,覆盖起点而不包含次日零点,避免靠猜测“当天最后一秒”去补边界。实际使用还要确认时间列类型、精度与时区,本次没有运行这个 MySQL 时间实验,不把它当作年龄表的实测结果。

5. 验证与收获

本次在 SQLite 内存数据库运行年龄实验,核对输出三列、AND 与 BETWEEN 的一致性、两端保留、范围外排除、NULL 与空表。还测试交换上下限,并用错误 OR、漏掉等号的开区间作为反例,确认测试能抓到它们。

MySQL BETWEEN 语义按官方文档核对;不由 SQLite 的类型转换结果推断所有 MySQL 字符串或时间比较。条件写法是否更快,也没有在本次测量。

区间题的第一步不是挑哪个关键字,而是画出边界:端点是否包含?两个条件要交集还是并集?未知值怎么处理?先把这几个问题写清楚,SQL 才是在准确表达范围,而不是拼出一句能执行的语句。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询