使用null的字符串连接似乎使整个字符串无效 - 这是Postgres中的所需行为吗?

时间:2016-01-21 21:34:08

标签: string postgresql concatenation

在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

我是否应该习惯这种行为与' ||'连接还是这个应该修复的东西?

4 个答案:

答案 0 :(得分:16)

这不是一个错误,它不是“怪异”。

SQL标准要求任何涉及null的表达式都会产生null。这不仅限于字符串连接,它也适用于计算,例如:42 * null返回null

这也适用于比较:42 > null产生null。所以比较它既不是真也不是假。虽然实际上这具有“假”的效果,但更多是因为它“不是真的”,而不是假的。但否定这样的表达会再次产生null,而不是“真实”。

由于null非常特殊,检查某些内容是否为空的唯一方法是使用运算符IS NULLIS NOT NULLx is null产生true或false,它永远不会产生null,因此使用is nullis 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)

是的,这是理想的行为。

这是一个非常有用的例子。假设您有一个人员表格,其中包含titlefirstnamenameaffixlastname字段。要建立一个全名,你可以简单地做到这一点。

COALESCE(title || ' ', '') || firstname || COALESCE(' ' || nameaffix, '') || ' ' || lastname

没有那种奇怪的行为,根据字段是否为空,将空间放置在正确的位置是非常有把握的。假设有一个强制性的名字和姓氏,则涵盖标题和名称附加的任何组合。

答案 2 :(得分:14)

从文档中引用

  

连接所有参数。忽略NULL参数。

实施例

concat('abcde', 2, NULL, 22) 

返回

abcde222

Documentation

中查看详情

答案 3 :(得分:2)

正如教我SQL的人所说,“ NULL表示'未知'并不意味着'零',或者'空字符串'意味着'未知'”。

这就是预期行为的原因,将未知值组合在一起的结果是未知的。

在设计新列时,这也值得考虑,对于它们来说,可为空意味着什么。