检查“空值或空值”的最佳方法
在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) , varchar , text或"char" (带引号),这些都是有用的数据types。 这是关于过时的数据types,有用性非常有限: char(n) ,short for: character(n) 。 另外, char和character是char(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)