可靠,但结果取决于字符集排序规则(collation),不是按字典序直观生效;MySQL中因collation大小写敏感性不同导致'M'是否匹配;PostgreSQL按Unicode码点排序中文;SQL Server忽略末尾空格影响边界。

WHERE子句里用BETWEEN比较字符串是否可靠?
可靠,但结果取决于字符集排序规则(collation),不是按字典序“直观”生效。比如 BETWEEN 'A' AND 'Z' 可能匹配到小写字母甚至数字,具体看数据库默认 collation 是 case-sensitive 还是 case-insensitive、是否包含扩展字符。
MySQL中BETWEEN 'a' AND 'm'为什么有时匹配到'M'有时不匹配?
根本原因是 collation 决定大小写行为:utf8mb4_0900_as_cs(区分大小写)下,'M' 和 'm' 是不同值,'M' 成立,所以不会被 <code>BETWEEN 'a' AND 'm' 包含;而 utf8mb4_0900_as_ci(不区分大小写)会把 'M' 视为等价于 'm',只要在范围内就匹配。
- 查当前字段 collation:执行
SHOW FULL COLUMNS FROM table_name LIKE 'column_name'; - 临时强制大小写敏感:用
COLLATE utf8mb4_0900_as_cs,例如WHERE name COLLATE utf8mb4_0900_as_cs BETWEEN 'a' AND 'm' - 避免隐式转换:如果字段是
VARCHAR但值含前导空格或全角字符,BETWEEN仍按字节/码点比较,可能不符合预期
PostgreSQL里BETWEEN对中文字符串的边界怎么算?
PostgreSQL 默认使用 LC_COLLATE 系统 locale 排序,中文通常按 Unicode 码点排序(如 U+4F60 > U+4F61),而非拼音或笔画。这意味着 BETWEEN '北京' AND '上海' 实际比较的是两个字符串首字符的 Unicode 值,后续字符只在首字符相等时才参与比较。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
-
'北京'(U+5317 U+4EAC)和'上海'(U+4E0A U+6D77):首字'上'(U+4E0A)'北'(U+5317),所以整个区间为空 —— 即使你直觉认为“北京”在“上海”之前 - 想按拼音排序?必须显式用
COLLATE "zh-CN-x-icu"(需启用 ICU 支持)或加函数:WHERE pinyin(name) BETWEEN pinyin('北京') AND pinyin('上海') - 纯英文+数字混合字段(如
'user10','user2'),BETWEEN按字符串逐位比较,'user2' > 'user10'成立(因为'2' > '1'),这不是数值比较
SQL Server中用BETWEEN查姓名范围时,结尾字符容易漏掉
SQL Server 的 VARCHAR / NVARCHAR 在比较时会忽略末尾空格(ANSI SQL 标准行为),导致 BETWEEN 'Li' AND 'Lu' 实际包含 'Li '(带空格)、'Lu\0'(如果存在截断)等值,且 'Lu' 本身会被匹配,但 'Luz' 不会 —— 因为 'Luz' > 'Lu'(第三位 'z' > '')。
- 确认字段是否真以指定字符结尾:用
LEN()和DATALENGTH()对比,检查有无隐藏空格 - 安全写法:改用开区间 + 字符串函数,例如查姓氏在 L–M 之间:
WHERE LEFT(name, 1) IN ('L', 'M')或WHERE name >= 'L' AND name - 如果字段是
CHAR(10)类型,所有值都被空格补满,BETWEEN 'Li' AND 'Lu'实际等价于BETWEEN 'Li ' AND 'Lu ',范围远超预期
字符区间匹配从来不是“字符串切片”操作,而是基于当前排序规则的一次完整字符串比较。真正要控制边界,得先看 COLLATION,再决定用 BETWEEN 还是拆解成 >= + ,最后一定用实际数据验证边界值——尤其是那些看起来“刚好卡在线上”的字符串。

















