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

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

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

目前我正在使用:

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

但是看起来有点丑。

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

最好的方法是什么?

415670 次浏览

如果后面可能有空的空格,可能没有更好的解决方案。COALESCE只是针对像你这样的问题。

表达式stringexpression = ''产生:

< p > TRUE . .for ''(或for 任何字符串仅由数据类型为char(n)的空格组成)
NULL . .for NULL
FALSE . .对于其他任何值

因此要检查:"stringexpression是NULL或empty":

(stringexpression = '') IS NOT FALSE

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

(stringexpression <> '') IS NOT TRUE

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

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

coalesce(stringexpression, '') = ''

但是顶部的表达式更快。

断言相反的语句更简单: "stringexpression既不是NULL也不是空的":

stringexpression <> ''

关于char(n)

这是关于数据类型char(n),简称:character(n)。(char / characterchar(1) / character(1)的缩写。)它的用法是不鼓励在Postgres:

在大多数情况下,应该使用textcharacter varying

不要将char(n)与其他有用的字符类型__ABC1, __ABC2, __ABC3或"char"(使用双引号)混淆。

char(n)中,空字符串与任何其他仅由空格组成的字符串没有区别。根据类型定义,所有这些都折叠为char(n)中的n空格。从逻辑上讲,上面的表达式也适用于char(n)——就像这些表达式一样(不适用于其他字符类型):

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

测试“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或空字符串”;text:

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
< p > Db<>fiddle here .
sqlfiddle子> < /

相关:

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

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

检查是否为空:

coalesce(string, '') = ''

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

coalesce(TRIM(string), '') = ''
如果数据库有大量的记录,那么null check可能需要更多的时间 你可以用不同的方式使用空检查,比如: 1) where columnname is null 2) where not exists() 3) WHERE (case when columnname is null then true end) < / p >

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

在MS SQL和PostgreSQL上都试过。

检查字符串的长度也是有效的,并且是紧凑的:

where length(stringexpression) > 0;

另一种方法是

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

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

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

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

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

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;

我错过了什么,选角吗?输入吗?

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

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

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

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

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

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