在WHERE子句使用LEN()同时过滤NULL与空值是否合理?
关于WHERE子句中使用LEN()过滤NULL与空值的合理性分析
问题背景
上周从同事处了解到LEN()函数不会解析NULL值:在SELECT语句中,它对NULL返回NULL而非0;但在WHERE语句中,Len(Col1) > 0却能同时过滤掉NULL和空值('')。想知道有没有理由不这么写?
测试代码
Drop table if exists #TestNull Create table #TestNull (Col1 varchar(20)) Insert into #TestNull(Col1) Values ('test'), ('1'),(Null),('') -- 在WHERE子句中使用LEN(),过滤NULL和空值 Select * From #TestNull Where Len(Col1) > 0 -- 在SELECT语句中查看LEN()的返回结果 Select Len(Col1) -- NULL返回NULL,空值返回0 From #TestNull;
为什么Len(Col1) > 0能同时过滤NULL和空值
SQL中,任何与NULL的比较运算都会返回UNKNOWN,而WHERE子句只会保留运算结果为TRUE的行:
- 当
Col1是NULL时,Len(Col1)返回NULL,NULL > 0结果为UNKNOWN,该行被过滤; - 当
Col1是空字符串''时,Len(Col1)返回0,0 > 0结果为FALSE,该行也被过滤。
不推荐这么用的几个理由
- 可读性差:不是所有开发者都熟悉
LEN()处理NULL的特性,看到Len(Col1) > 0时,可能误以为只过滤了空值,忽略了NULL的处理。相比之下,WHERE Col1 IS NOT NULL AND Col1 <> ''的逻辑更直白,后续维护时不容易产生误解。 - 性能隐患:如果
Col1字段上有索引,Len(Col1) > 0属于函数调用,数据库通常无法直接利用索引(除非提前创建了基于LEN(Col1)的计算列索引),在数据量较大时,可能导致全表扫描,影响查询效率。而显式的IS NOT NULL和<> ''更易被优化器识别,能更好地利用现有索引。 - 类型兼容问题:如果后续字段类型发生变更(比如从
varchar改为非字符类类型),LEN()可能触发隐式转换,带来意外结果;而显式判断的兼容性更强。
总结
如果是小型数据集且团队成员都清楚LEN()的特性,用Len(Col1) > 0过滤没问题;但从长期维护、可读性和性能角度,更推荐使用显式的条件判断WHERE Col1 IS NOT NULL AND Col1 <> ''。
内容的提问来源于stack exchange,提问作者BW1
相关产品推荐
相关产品推荐

