LOWER()是标准SQL函数,用于将字符串中字母转为小写,主流数据库均支持;MySQL对中文等非ASCII字符返回原值,因无大小写概念;使用时需注意性能、NULL处理及索引失效风险。

SQL里用LOWER()转小写,但得看数据库类型
LOWER() 是标准 SQL 函数,主流数据库(PostgreSQL、SQL Server、SQLite、Oracle)都支持,但 MySQL 有点特殊:它默认不区分大小写比较,且 LOWER() 对 utf8mb4 字符集下的中文、emoji 等可能返回原值(不是报错,是“没变化”)。如果字段存的是中文,LOWER() 不会把它变小写——因为中文没有大小写概念,函数只是“安全绕过”,不是 bug。
- MySQL 中对英文字段用
LOWER(name)没问题;对含中文的VARCHAR字段执行LOWER(),结果不变,别误以为函数失效 - PostgreSQL 对非 ASCII 字符(如带重音的法语字母)能正确小写化,前提是列编码为
UTF8且 locale 支持 - SQL Server 的
LOWER()依赖列的排序规则(collation),若为SQL_Latin1_General_CP1_CI_AS,对德语 ß 会转成ss;而Latin1_General_100_CI_AS_SC_UTF8下行为更符合 Unicode 标准
SELECT 中直接用LOWER()最常见,但别漏了别名
直接在查询字段里套用即可,不需要额外声明或导入。但如果不加别名,返回的列名就是 lower(name) 这种带括号的原始表达式,在应用层取值容易出错(比如 Python 的 row['lower(name)'] 很别扭)。
- 写成
SELECT LOWER(username) AS username FROM users,保持字段名干净 - 多个字段要转?可以并列:
SELECT LOWER(first_name), LOWER(last_name), email FROM contacts - 和
WHERE连用时注意性能:WHERE LOWER(email) = 'ADMIN@EXAMPLE.COM'会导致该列索引失效(除非建函数索引,如 PostgreSQL 的CREATE INDEX idx_email_lower ON users (LOWER(email)))
UPDATE 时用LOWER()要格外小心
更新前务必确认目标字段是否允许空值、长度是否足够(虽然小写一般不增长度,但某些 Unicode 规范下,如土耳其语的 I → i 是单字符,而 İ(带点大写 I)→ i 也是单字符,基本安全;但极端情况如德语 SS 在特定 collation 下可能映射为 ß,不过 LOWER() 本身不负责这种转换)。
- 先查再改:
SELECT id, name, LOWER(name) FROM products WHERE name != LOWER(name),确认哪些行真需要改 - UPDATE 语句示例:
UPDATE users SET email = LOWER(email) WHERE email IS NOT NULL - 千万别写成
UPDATE users SET email = LOWER(email)不加WHERE——全表更新可能锁表、触发大量日志、甚至因字段长度限制导致截断(比如原字段定义为VARCHAR(20),但底层编码让某个大写字符占 3 字节、小写占 4 字节——极罕见,但 utf8mb4 + 某些扩展字符组合下理论上存在)
替代方案:有些场景LOWER()不是最优解
如果只是为了「忽略大小写比较」,用函数包裹字段不如改写条件。例如匹配邮箱时,与其 WHERE LOWER(email) = LOWER(?),不如用数据库原生的大小写不敏感比较方式:
- PostgreSQL:直接
WHERE email ILIKE 'ADMIN@EXAMPLE.COM'(ILIKE是大小写不敏感的LIKE) - MySQL:确保字段 collation 是
utf8mb4_unicode_ci或类似_ci(case-insensitive)结尾的,那么WHERE email = 'ADMIN@EXAMPLE.COM'自动不区分大小写 - SQL Server:用
COLLATE Latin1_General_CI_AS显式指定,如WHERE email COLLATE Latin1_General_CI_AS = 'ADMIN@EXAMPLE.COM'
这些方式通常能走索引,比 LOWER() 更快。只有当你明确需要「存储小写形式」或「输出统一格式」时,才真正需要 LOWER()。

















