在Postgres中:
select 'test' || null returns null
我原本以为它会返回' test'。
这是理想的行为吗?似乎奇怪的是,使用空值进行字符串连接会使整个字符串无效...
参考pg docs:http://www.postgresql.org/docs/9.1/static/functions-string.html
"注意:在PostgreSQL 8.3之前,由于存在从这些数据类型到文本的隐式强制,这些函数也会默默地接受几个非字符串数据类型的值。这些强制措施已被删除,因为它们经常引起令人惊讶的行为。但是,字符串连接运算符(||)仍然接受非字符串输入,只要至少有一个输入是字符串类型,如表9-6所示。对于其他情况,如果您需要复制以前的行为,请在文本中插入明确的强制。"
鉴于此,使用他们的concat字符串函数示例:
concat(str" any" [,str" any" [,...]]) text连接所有参数。 NULL参数被忽略。 concat(' abcde',2,NULL,22)>> abcde222
我是否应该习惯这种行为与' ||'连接还是这个应该修复的东西?
答案 0 :(得分:16)
这不是一个错误,它不是“怪异”。
SQL标准要求任何涉及null
的表达式都会产生null
。这不仅限于字符串连接,它也适用于计算,例如:42 * null
返回null
。
这也适用于比较:42 > null
产生null
。所以比较它既不是真也不是假。虽然实际上这具有“假”的效果,但更多是因为它“不是真的”,而不是假的。但否定这样的表达会再次产生null
,而不是“真实”。
由于null
非常特殊,检查某些内容是否为空的唯一方法是使用运算符IS NULL
或IS NOT NULL
。 x is null
产生true或false,它永远不会产生null
,因此使用is null
或is not null
运算符永远的表达式将返回null - 所以这是我上面的陈述是个例外(感谢Jonathan指出这一点)。
另一个 - 可能令人惊讶 - 关于null
值的事实是聚合函数如何处理它们。虽然表达式 4 + 5 + null
产生null,但sum()
上的那些(列)值会产生9,因为聚合忽略 null
值。
鉴于下表:
col1
--------
1
2
3
null
sum(col1)
将返回6,avg(col1)
将返回2
(sum = 6,添加的元素数量:3)
答案 1 :(得分:14)
是的,这是理想的行为。
这是一个非常有用的例子。假设您有一个人员表格,其中包含title
,firstname
,nameaffix
和lastname
字段。要建立一个全名,你可以简单地做到这一点。
COALESCE(title || ' ', '') || firstname || COALESCE(' ' || nameaffix, '') || ' ' || lastname
没有那种奇怪的行为,根据字段是否为空,将空间放置在正确的位置是非常有把握的。假设有一个强制性的名字和姓氏,则涵盖标题和名称附加的任何组合。
答案 2 :(得分:14)
答案 3 :(得分:2)
正如教我SQL的人所说,“ NULL表示'未知'并不意味着'零',或者'空字符串'意味着'未知'”。
这就是预期行为的原因,将未知值组合在一起的结果是未知的。
在设计新列时,这也值得考虑,对于它们来说,可为空意味着什么。