Postgresql:当使用WHERE col NOT LIKE "foo"时如何获取空值?



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中,它说:

布尔数据类型的值为truefalse未知的真值有时由null值表示。

它以一种奇特的方式表示,将某个值与NULL值进行比较将导致NULL。可以这样想:如果一个未知字符串像foo,那么它就是未知的。

有几种方法可以得到你想要的东西:

  1. 使用coalesce:

    WHERE coalesce(my_text_column, 'foo') LIKE 'foo%'
    
  2. 使用OR:

    WHERE my_text_column LIKE 'foo%' OR my_text_column IS NULL
    
  3. 使用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;也起作用。

最新更新