检查Postgres sql语句中值是否为空或空字符串的最佳方法是什么?

Value可以是一个很长的表达式,所以在检查时最好只写一次。

目前我正在使用:

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

但是看起来有点丑。

Stringexpression可以是char(n)列,也可以是包含char(n)列的表达式,后面带空格。

最好的方法是什么?


当前回答

很多答案都是最短的,但不一定是最好的如果列中有很多空。分解检查可以让优化器更快地计算检查,因为它不需要在其他条件上工作。

(stringexpression IS NOT NULL AND trim(stringexpression) != '')

字符串比较不需要计算,因为第一个条件是假的。

其他回答

检查是否为空:

coalesce(string, '') = ''

检查null, empty和空格(修剪字符串)

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

表达式stringexpression = "得到:

真正的. .对于"(或任何仅由数据类型为char(n)的空格组成的字符串) 空. .为零 假. .还有其他的吗

所以要检查:"stringexpression is NULL or empty":

(stringexpression = '') IS NOT FALSE

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

(stringexpression <> '') IS NOT TRUE

适用于包括char(n)在内的任何字符类型。关于比较操作符的手册。

或者使用没有trim()的原始表达式,这对于char(n)是代价高昂的噪声(见下文),或者对于其他字符类型是不正确的:仅由空格组成的字符串将作为空字符串传递。

coalesce(stringexpression, '') = ''

但是顶部的表达式更快。

相反的断言甚至更简单:"stringexpression既不是NULL也不是empty":

stringexpression <> ''

关于char (n)

这是关于数据类型char(n),字符(n)的缩写。(char / character是char(1) / character(1)的缩写。)不鼓励在Postgres中使用:

在大多数情况下,应该使用文本或字符变化来代替。

不要将char(n)与其他有用的字符类型varchar(n)、varchar、text或“char”(带双引号)混淆。

在char(n)中,空字符串与其他仅由空格组成的字符串没有什么不同。所有这些都以char(n)为单位折叠成n个空格。从逻辑上讲,上面的表达式也适用于char(n)——就像这些表达式一样(不适用于其他字符类型):

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

Demo

空字符串在转换为char(n)时等于任何空格字符串:

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

测试“null或空字符串”与char(n):

SELECT stringexpression 
     , stringexpression = ''                   AS base_test
     , (stringexpression = '')  IS NOT FALSE   AS test1
     , (stringexpression <> '') IS NOT TRUE    AS test2
     , coalesce(stringexpression, '') = ''     AS coalesce1
     , coalesce(stringexpression, '  ') = '  ' AS coalesce2
     , coalesce(stringexpression, '') = '  '   AS coalesce3
FROM  (
   VALUES
     ('foo'::char(5))
   , ('')
   , ('   ')                -- not different from '' in char(n)
   , (NULL)
   ) sub(stringexpression);

结果:

 stringexpression | base_test | test1 | test2 | coalesce1 | coalesce2 | coalesce3 
------------------+-----------+-------+-------+-----------+-----------+-----------
 foo              | f         | f     | f     | f         | f         | f
                  | t         | t     | t     | t         | t         | t
                  | t         | t     | t     | t         | t         | t
 null             | null      | t     | t     | t         | t         | t

测试“null或空字符串”文本:

SELECT stringexpression 
     , stringexpression = ''                   AS base_test
     , (stringexpression = '')  IS NOT FALSE   AS test1
     , (stringexpression <> '') IS NOT TRUE    AS test2
     , coalesce(stringexpression, '') = ''     AS coalesce1
     , coalesce(stringexpression, '  ') = '  ' AS coalesce2
     , coalesce(stringexpression, '') = '  '   AS coalesce3
FROM  (
   VALUES
     ('foo'::text)
   , ('')
   , ('   ')                -- different from '' in a sane character types
   , (NULL)
   ) sub(stringexpression);

结果:

 stringexpression | base_test | test1 | test2 | coalesce1 | coalesce2 | coalesce3 
------------------+-----------+-------+-------+-----------+-----------+-----------
 foo              | f         | f     | f     | f         | f         | f
                  | t         | t     | t     | t         | f         | f
                  | f         | f     | f     | f         | f         | f
 null             | null      | t     | t     | t         | t         | f

db < >小提琴 老sqlfiddle

相关:

使用数据类型“文本”存储字符串的任何缺点?

我喜欢yglodt的答案,但对于大的集合和大的字符串来说,计算准确的长度可能是昂贵的,所以我选择:

coalesce(trim('a') > '','f')

如果数据库有大量的记录,那么空检查会花费更多的时间 你可以用不同的方式使用空检查,比如: 1)其中columnname为空 2)如果不存在() 3) WHERE(当columnname为null时,则为true结束)

发现这篇文章寻找一个解决方案,“不要显示我的数据是”(空白或单一空格字符)或null”。在我的例子中,我们只想显示填充了这些值的用户记录。我希望这样的回应能帮助到其他有同样想法的人。上述答案在我的案例中并不适用。

我们的应用程序使用postgres运行rails。查看rails如何构建.where的查询。不是(company_website: [nil, "])在我们的应用程序,这工作得很好,我可以看到控制台的结果SQL语句。

WHERE NOT ((contacts.company_website = " OR contacts.company_website IS NULL))

我添加了这一点,它的工作作为预期。