在my_text_column
上使用WHERE
子句和NOT LIKE
时,会跳过null
值。
为什么以及如何获得它?
SELECT count(id) FROM public.mytable;
count
-------
91
SELECT count(id) FROM public.mytable WHERE my_text_column LIKE 'foo';
count
-------
59
SELECT count(id) FROM public.mytable WHERE my_text_column NOT LIKE 'foo';
count
-------
0
SQL标准在框架4.4.2中对NULL进行了说明:
[…]空值既不等于任何其他值,也不等于任何其它值–未知是否等于任何给定值[…]
在4.4.3.3中,它说:
布尔数据类型的值为true或false。未知的真值有时由null值表示。
它以一种奇特的方式表示,将某个值与NULL值进行比较将导致NULL。可以这样想:如果一个未知字符串像foo
,那么它就是未知的。
有几种方法可以得到你想要的东西:
-
使用
coalesce
:WHERE coalesce(my_text_column, 'foo') LIKE 'foo%'
-
使用
OR
:WHERE my_text_column LIKE 'foo%' OR my_text_column IS NULL
-
使用
UNION ALL
:SELECT count(id) FROM (SELECT id FROM public.mytable WHERE my_text_column LIKE 'foo%' UNION ALL SELECT id FROM public.mytable WHERE my_text_column IS NULL) AS subq;
类似的查询使索引变得复杂。
SELECT count(*) FROM public.mytable
WHERE my_text_colum not LIKE 'foo' or my_text_colum is null;
来自手册:
如果模式不包含百分号或下划线,则pattern只表示字符串本身;在这种情况下,LIKE的行为就像等于运算符。
因此SELECT count(*) FROM tbl3 WHERE txt <> 'foo' or txt is null;
也起作用。