检查“空值或空值”的最佳方法

在Postgres sql语句中检查值是空还是空string的最佳方法是什么?

价值可以是长期的expression,所以最好只写一次。

目前我正在使用:

coalesce( trim(stringexpression),'')='' 

但它看起来有点难看。

stringexpressionexpression式可以是char(n)列或包含具有尾随空格的char(n)列的expression式。

什么是最好的方法?

expression式stringexpression = ''expression式stringexpression = ''产生:

TRUE .. for '' (或者仅包含数据types为char(n)空格的任何string)
NULL ..为NULL
FALSE ..其他任何东西

所以要检查: stringexpression是NULL还是空的”

 (stringexpression = '') IS NOT FALSE 

或者相反的方法(可能更容易阅读):

 (stringexpression <> '') IS NOT TRUE 

适用于任何字符types,包括几乎无用的过时char(n)
有关比较运算符的手册。

或者使用你已经拥有的expression式,只是没有对char(n)无用的trim() (见下文),或者它将包括对其他字符types只包含空格的string:

 coalesce(stringexpression, '') = '' 

但是顶部的expression速度更快。

断言相反: stringexpression既不是空也不空”更简单:

 stringexpression <> '' 

关于char(n)

不要将此数据types与其他字符types混淆,如varchar(n)varchartext"char" (带引号),这些都是有用的数据types。 这是关于过时的数据types,有用性非常有限: char(n) ,short for: character(n) 。 另外, charcharacterchar(1) / character(1) (同一事物)的简称。

char(n) (与其他stringtypes不同!)一个空string没有任何其他string由只有空格组成。 所有这些被折叠到每个types定义的char(n) n个空格。 从逻辑上讲,这也适用于char(n)

 coalesce(stringexpression, '') = '' 

就像这些(这不适用于其他字符types)一样:

 coalesce(stringexpression, ' ') = ' ' coalesce(stringexpression, '') = ' ' 

演示

空string等于转换为char(n)时的任何空格string:

 SELECT ''::char(5) = ''::char(5) AS eq1 ,''::char(5) = ' '::char(5) AS eq2 ,''::char(5) = ' '::char(5) AS eq3; 
 eq1 | eq2 | eq3 ----+-----+---- t | t | t 

char(n)testing“null或空string”:

 SELECT stringexpression ,stringexpression = '' AS simple_test ,(stringexpression = '') IS NOT FALSE AS test1 ,(stringexpression <> '') IS NOT TRUE AS test2 ,coalesce(stringexpression, '') = '' AS test_coalesce1 ,coalesce(stringexpression, ' ') = ' ' AS test_coalesce2 ,coalesce(stringexpression, '') = ' ' AS test_coalesce3 FROM ( VALUES ('foo'::char(5)) , ('') , (NULL) , (' ') -- not different from '' in char(n) ) sub(stringexpression); 
  stringexpression | simple_test | test1 | test2 | test_coalesce1 | test_coalesce2 | test_coalesce3 ------------------+-------------+-------+-------+----------------+----------------+---------------- foo | f | f | f | f | f | f | t | t | t | t | t | t | | t | t | t | t | t | t | t | t | t | t | t 

texttesting“null或空string”

 SELECT stringexpression ,stringexpression = '' AS simple_test ,(stringexpression = '') IS NOT FALSE AS test1 ,(stringexpression <> '') IS NOT TRUE AS test2 ,coalesce(stringexpression, '') = '' AS test_coalesce1 ,coalesce(stringexpression, ' ') = ' ' AS test_coalesce2 ,coalesce(stringexpression, '') = ' ' AS test_coalesce3 FROM ( VALUES ('foo'::text) , ('') , (NULL) , (' ') -- different from '' in a sane character type like text ) sub(stringexpression); 
  stringexpression | simple_test | test1 | test2 | test_coalesce1 | test_coalesce2 | test_coalesce3 ------------------+-------------+-------+-------+----------------+----------------+---------------- foo | f | f | f | f | f | f | t | t | t | t | f | f | | t | t | t | t | f | f | f | f | f | f | f 

dbfiddle 在这里
旧的SQL小提琴

有关:

  • 使用数据types“文本”存储string的任何缺点?

检查null和empty:

 coalesce(string, '') = '' 

检查空,空和空格(修剪string)

 coalesce(TRIM(string), '') = '' 

如果可能有空的尾随空间,可能没有更好的解决scheme。 COALESCE只是像你的问题。

我比较可空字段的优先方式是:NULLIF(nullablefield,:ParameterValue)IS NULL和NULLIF(:ParameterValue,nullablefield)IS NULL。 这很麻烦,但具有通用性,而在某些情况下,合并是不可能的。

NULLIF的第二个反例使用是因为如果第一个参数为空,“NULLIF(nullablefield,:ParameterValue)IS NULL”将始终返回“true”。

如果数据库有大量的logging,然后null check可以花费更多的时间,你可以使用空检查以不同的方式,如:1) where columnname is null 2) where not exists() 3) WHERE (case when columnname is null then true end)