Postgresql
文本和 NULL 值的連接如何返回非空結果?
斷言 1
連接運算符
||
可以連接任何字元串類型的值,返回text
. 在 Postgres 中,每種類型都有一個文本表示,並且可以轉換為text
. 因此,引用手冊:但是,字元串連接運算符 (
||
) 仍然接受非字元串輸入,只要至少一個輸入是字元串類型有關的:
斷言 2
連接一個或多個
NULL
值會產生結果NULL
。test=# SELECT (text 'foo' || NULL) IS NULL test-# , (text 'bar' || char '1' || NULL ) IS NULL test-# , (NULL::bigint || text 'baz') IS NULL; ?column? | ?column? | ?column? ----------+----------+---------- t | t | t
問題
是否可以連接 a
text
和一個NULL
值並獲得非空結果?換句話說,這怎麼可能?
test=# SELECT col IS NULL AS col_is_null test-# , (text 'foo' || col) IS NULL AS result_is_null test-# FROM tbl; col_is_null | result_is_null -------------+---------------- t | f
適用於任何 Postgres 版本。
我的一個客戶偶然發現了這個,依靠結果是
NULL
,我發現它很有趣,可以分享。這是一個有點技巧的問題,因為我知道答案。
注意:
CASE
或COALESCE
捕捉NULL
值通常是好的風格,但這不是這個問題的目的。這是關於與實際NULL
值的連接,使用連接運算符||
並且仍然得到非空結果。
那是因為 PostgreSQL 中的 CAST 數組類型系統有點奇怪(乍一看):-)
text || text[]
使雙方都被強制為數組。CREATE TABLE tbl (col text ARRAY); INSERT INTO tbl SELECT NULL; SELECT col IS NULL AS col_is_null, (text 'foo' || col) IS NULL AS result_is_null FROM tbl; col_is_null | result_is_null -------------+---------------- t | f (1 row)
另一個可能更能說明問題的例子:
create temp table x as select 'foo' test, null::text[] col; SELECT test, col, test || col from x; test | col | ?column? ------+------+---------- foo | NULL | {foo} (1 row)