最常用方法是ORDER BY LENGTH(column) DESC LIMIT 1,但需排除NULL和空字符串;多值并列时应改用子查询求最大长度再匹配;注意CHAR_LENGTH()与LENGTH()在多字节字符下的语义差异。

用 LENGTH() 和 ORDER BY ... DESC 找最长文本
直接按字段长度降序排序,再取第一条,是最常用也最可靠的方法。注意不同数据库对空值(NULL)和空字符串('')的处理一致:它们长度都是 0,不会干扰最大值查找。
示例(查 description 字段最长的一条记录):
SELECT * FROM products ORDER BY LENGTH(description) DESC LIMIT 1;
-
LENGTH()在 MySQL、PostgreSQL、SQLite 中都可用;SQL Server 要换成LEN() - 如果存在多条等长的“最长记录”,该写法只返回其中一条(无稳定顺序保证),需加额外条件(如
id)才能确定唯一性 - 字段含前导/尾随空格时,
LENGTH()会把它们算进去;若想忽略空格,可套一层TRIM():LENGTH(TRIM(description))
用窗口函数 ROW_NUMBER() 精确获取所有最长项
当需要返回所有长度等于最大值的记录(不止一条),就不能只靠 LIMIT 1。窗口函数是更严谨的选择,尤其适合 PostgreSQL、SQL Server、MySQL 8.0+。
示例(查出所有 name 长度等于最大值的行):
SELECT id, name FROM (
SELECT id, name,
ROW_NUMBER() OVER (ORDER BY LENGTH(name) DESC) AS rn,
MAX(LENGTH(name)) OVER() AS max_len
FROM users
) t WHERE LENGTH(name) = max_len;- 不能只依赖
rn = 1,因为ROW_NUMBER()会强制编号,相同长度也会被分出先后;必须显式比对LENGTH(name) = max_len -
MAX(LENGTH(...)) OVER()是关键,它把全局最大长度广播到每一行,避免子查询或多次扫描 - SQLite 不支持窗口函数(截至 3.45),此时只能用子查询方式模拟
小心 CHAR_LENGTH() 和 LENGTH() 的字节 vs 字符差异
在多字节字符集(如 UTF-8)下,LENGTH() 返回字节数,CHAR_LENGTH() 返回字符数——中文、emoji 等一个字符占多个字节,两者结果可能不同。
- MySQL 默认用
LENGTH()返回字节数,CHAR_LENGTH()才是真实字符数;业务上通常关心“字符长度”(比如限制输入 20 个汉字),应优先用CHAR_LENGTH() - PostgreSQL 中
LENGTH()等价于其他数据库的CHAR_LENGTH(),即按字符计;但显式写CHAR_LENGTH()更具可移植性 - SQL Server 的
LEN()忽略尾部空格,而DATALENGTH()返回字节数(含空格),行为更接近 MySQL 的LENGTH()
性能要注意:大表上 LENGTH() 无法走索引
LENGTH() 是计算型函数,对字段套用后无法利用普通 B-tree 索引加速排序,全表扫描不可避免。
- 如果该查询高频执行且表很大,考虑增加生成列(generated column)并为其建索引(MySQL 5.7+、PostgreSQL 12+ 支持):
- 例如添加
name_len INT AS (CHAR_LENGTH(name)) STORED,再在name_len上建索引 - 临时方案:用覆盖索引减少回表,比如只查
id和name,避免SELECT *带来大量 I/O
实际应用中,最容易被忽略的是字符集语义混淆——你以为在比“几个字”,其实数据库在比“几个字节”。上线前务必用含中文、emoji 的测试数据验证结果是否符合业务预期。

















