Postgresql

文本和 NULL 值的連接如何返回非空結果?

  • March 29, 2019

斷言 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

問題

是否可以連接 atext和一個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,我發現它很有趣,可以分享。

這是一個有點技巧的問題,因為我知道答案。

注意: CASECOALESCE捕捉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)

引用自:https://dba.stackexchange.com/questions/233522