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

时间:2014-05-20 17:13:52

标签: sql database postgresql null coalesce

在Postgres sql语句中检查value是null还是空字符串的最佳方法是什么?

值可以是长表达式,因此最好只检查一次。

目前我正在使用:

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

但它看起来有点难看。

stringexpression可能是char(n)列或包含带有尾随空格的char(n)列的表达式。

最好的方法是什么?

12 个答案:

答案 0 :(得分:213)

表达式stringexpression = ''产生:

TRUE ..适用于''(或任何字符串,仅包含数据类型为char(n)的空格)
NULL .. NULL FALSE ..对于任何其他

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

(stringexpression = '') IS NOT FALSE

或反向方法(可能更容易阅读):

(stringexpression <> '') IS NOT TRUE

适用于any character type,包括过时的char(n),这几乎没用过 The manual about comparison operators.

使用您已有的表达式,只是没有对trim()无效的char(n)(见下文),或者它将包括在测试中仅包含其他字符类型的空格的字符串:

coalesce(stringexpression, '') = ''

但是顶部的表达式更快。<​​/ p>

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

stringexpression <> ''

关于char(n)

不要将此数据类型与varchar(n), varchar, text or "char"(带引号)等其他字符类型混淆,后者都是有用的数据类型。这是关于过时的数据类型,其用途非常有限:char(n),简称:character(n)。此外,charcharacterchar(1) / character(1)的缩写(同样的事情)。

char(n)中(与其他字符串类型不同!)空字符串与仅包含空格的任何其他字符串没有区别。根据类型的定义,所有这些都被折叠到char(n)中的 n 空间。从逻辑上讲,这也适用于char(n)

coalesce(stringexpression, '') = ''

与这些一样多(对其他字符类型不起作用):

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

演示

当转换为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  

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

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

使用text

测试“null或空字符串”
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 here
<子> Old SQL Fiddle

相关:

答案 1 :(得分:29)

检查null和空:

coalesce(string, '') = ''

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

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

答案 2 :(得分:2)

如果可能有空的尾随空格,可能没有更好的解决方案。 COALESCE仅适用于像您这样的问题。

答案 3 :(得分:1)

我看到人们使用的是stringexpression > ''。这可能不是最快的,但恰好是最短的之一。

在MS SQL和PostgreSQL上尝试过它。

答案 4 :(得分:0)

我比较可空字段的优先方法是: NULLIF(nullablefield,:ParameterValue)IS NULL AND NULLIF(:ParameterValue,nullablefield)IS NULL。这很麻烦但是普遍使用,而Coalesce在某些情况下是不可能的。

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

答案 5 :(得分:0)

如果数据库包含大量记录,那么null check可能需要更多时间 你可以用不同的方式使用null检查,例如: 1)where columnname is null 2)where not exists() 3)WHERE (case when columnname is null then true end)

答案 6 :(得分:0)

检查字符串的长度也可以并且很紧凑:

where length(stringexpression) > 0;

答案 7 :(得分:0)

另一种方法是

nullif(trim(stringExpression),'') is not null

答案 8 :(得分:0)

在遇到类似情况时,我必须这样做。我的表格定义如下:

id(bigint)|name (character varying)|results(character varying)
1 | "Peters"| [{"jk1":"jv1"},{"jk1":"jv2"}]
2 | "Russel"| null

要过滤掉结果列中包含null或空的内容,有效的方法是:

SELECT * FROM tablename where results NOT IN  ('null','{}'); 

这将返回结果中不为空的所有行。

我不确定如何解决此查询,以返回与结果不为空的所有行相同的行。

SELECT * FROM tablename where results is not null; 

---嗯,我想念的是什么?有输入吗?

答案 9 :(得分:0)

发现这篇文章正在寻找“不向我显示数据为”(空白或单个空格字符)或空值的解决方案。就我而言,我们只想显示填充了这些值的用户记录。我希望这个回复可以帮助另一个寻找相同的人。上面的答案在我的情况下不起作用。

我们的应用程序正在使用 postgres 运行 rails。看看 rails 如何在我们的应用程序中构建 .where.not(company_website: [nil, '']) 的查询,它工作得很好,我可以在控制台中看到生成的 sql 语句。

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

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

答案 10 :(得分:0)

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

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

答案 11 :(得分:-1)

很多答案是最短的方法,如果列中有很多空值,则不一定是最好的方法。分解支票可使优化器更快地评估支票,因为它不必在其他条件下进行工作。

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

由于第一个条件为假,因此不需要评估字符串比较。