Postgresql

string_agg 沒有記錄時返回空字元串

  • October 6, 2019

我正在嘗試在 PostgreSQL 查詢中返回一個文本欄位,其形式為

'stringOne' || string_agg(field, ',') || 'stringTwo'

對於 group 子句中的某些元素,wherefield始終為 null。我希望並期望stringOnestringTwo在這種情況下最終得到NULL.

為什麼會這樣,我該如何完成我想做的事情?

例子

假設我有桌子

foo                 bar
+----+--------+     +----+-------+--------------+
| id | name   |     | id | fooid | baz          |
+----+--------+     +----+-------+--------------+
|  1 | FooOne |     |  1 |     1 | FooOneBazOne |
|  2 | FooTwo |     |  2 |     1 | FooTwoBazTwo |
+----+--------+     +----+-------+--------------+

我執行查詢

SELECT
 foo.name AS foo,
 'Bazzes: ' || string_agg(bar.baz, ', ') AS bazzes
FROM
 foo LEFT JOIN bar ON bar.fooid = foo.id
GROUP BY
 foo.name

然後我想(並期望)得到結果集

+--------+------------------------------------+
| foo    | bazzes                             |
+--------+------------------------------------+
| FooOne | Bazzes: FooOneBazOne, FooOneBazTwo |
| FooTwo | Bazzes:                            |  <== NOT NULL
+--------+------------------------------------+

但相反,第二行是('FooTwo', NULL). 如何修改此查詢以使第二行返回('FooTwo', 'Bazzes: ')

用於COALESCE擷取和替換NULL值:

SELECT f.name AS foo
    , 'Bazzes: ' || COALESCE(string_agg(b.baz, ', '), '') AS bazzes
FROM   foo f
LEFT   JOIN bar b ON b.fooid = f.id
GROUP  BY 1;

concat()是您發現自己的另一個方便的選擇,特別是連接多個值。不過,我建議使用變體concat_ws()(“帶分隔符”)以避免尾隨空格。

concat_ws(' ', 'Bazzes:', string_agg(b.baz, ', ')) AS bazzes

為什麼NULL

NULL如果所有源欄位都是NULL(準確地說,沒有非空值),則幾乎所有聚合函式都返回-count()由於實際原因是例外。手冊:

需要注意的是,除了 之外count,這些函式在沒有選擇行時返回空值。特別是,sumof no rows 返回 null,而不是預期的零,並且array_agg在沒有輸入行時返回 null 而不是空數組。必要時,該coalesce 函式可用於將零或空數組替換為 null。

有關的:

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