2017-05-27 161 views
1

使用NULL。因此,像SELECT c FROM t WHERE c > 0将其中c既没有NULL和大于零(因为当cNULL条件c > 0评估为NULL)从t选择所有的行。在WHERE子句

我不确定是否我可以依靠这种行为,因为WHERE NULL看起来像一个黑客。 (可能更正确的方法是使用CASE表达式。)

+0

您是否试过'SELECT c FROM t WHERE c is null'? –

+0

@YuvalPruss我需要'C'既不是'NULL',并且大于零。 –

+0

所以:'SELECT c FROM t WHERE c is null or c> 0 –

回答

2

这不是Postgres特定的行为。它是如何定义SQL以及SQL如何定义值的。

条件:

WHERE c > 0 

肯定条件。它将c > 0评估的所有行保留为true。

cNULL时,则c > 0评估为NULLNULL不正确(也不是false),因此c > 0会过滤掉NULL值。几乎所有的比较NULL返回NULL

另外:

WHERE NOT (c > 0) 

也过滤掉NULL值,因为NOT NULL是一样的NULL

如果你想保持NULL值,我建议是明确的:

WHERE c > 0 OR c IS NULL 
+0

啊我看到了,所以当做布尔运算'NULL'基本上是一个未知的,使一些结果也未知。但是,无论其他谓词如何评估,“真实或......”和“假和......”总是有确定性的结果。 –

+0

而且,'SELECT'只保留'TRUE'行,并且抛弃'FALSE'和未知行......对吧? –

+1

@ZizhengTai是的,没错。 – melpomene

1

根据我的the documentation解释,你可以依靠的事实,只有非空的元素将被退回:

当任一输入为空时,普通比较运算符产生null(表示“未知”),不是真或假。例如,7 = NULL会产生null,7 <> NULL。当发生这种情况是不适合的,使用IS [NOT] DISTINCT FROM谓词:

a IS DISTINCT FROM b 
a IS NOT DISTINCT FROM b 

对于非空输入,有别于相同的<>运算符。但是,如果两个输入都为空,则返回false,并且如果只有一个输入为空,则返回true。同样,对于非空输入,IS NOT DISTINCT FROM与=相同,但当两个输入都为空时它将返回true,而当只有一个输入为空时,则返回false。因此,这些谓词有效地表现为空值是正常的数据值,而不是“未知”。

要检查值是否为或不为空,则使用谓词:

expression IS NULL 
expression IS NOT NULL 

或相当,但非标准,谓词:

expression ISNULL 
expression NOTNULL 

不要写expression = NULL,因为NULL不等于NULL。 (空值表示未知值,并且不知道两个未知值是否相等。)