在Postgres sql语句中检查value是null还是空字符串的最佳方法是什么?
值可以是长表达式,因此最好只检查一次。
目前我正在使用:
coalesce( trim(stringexpression),'')=''
但它看起来有点难看。
stringexpression
可能是char(n)
列或包含带有尾随空格的char(n)
列的表达式。
最好的方法是什么?
答案 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)
。此外,char
和character
是char(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
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) != '')
由于第一个条件为假,因此不需要评估字符串比较。