Mic*_*ood 8 postgresql null aggregate concat
我正在尝试在格式为 PostgreSQL 查询中返回一个文本字段
'stringOne' || string_agg(field, ',') || 'stringTwo'
Run Code Online (Sandbox Code Playgroud)
对于 group 子句中的某些元素, wherefield始终为 null。我想要并期望stringOnestringTwo在这种情况下结束,但我得到NULL.
为什么会这样,我如何完成我想要做的事情?
假设我有桌子
foo bar
+----+--------+ +----+-------+--------------+
| id | name | | id | fooid | baz |
+----+--------+ +----+-------+--------------+
| 1 | FooOne | | 1 | 1 | FooOneBazOne |
| 2 | FooTwo | | 2 | 1 | FooTwoBazTwo |
+----+--------+ +----+-------+--------------+
Run Code Online (Sandbox Code Playgroud)
我运行查询
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
Run Code Online (Sandbox Code Playgroud)
然后我想要(并期望)得到结果集
+--------+------------------------------------+
| foo | bazzes |
+--------+------------------------------------+
| FooOne | Bazzes: FooOneBazOne, FooOneBazTwo |
| FooTwo | Bazzes: | <== NOT NULL
+--------+------------------------------------+
Run Code Online (Sandbox Code Playgroud)
但相反,第二行是('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;
Run Code Online (Sandbox Code Playgroud)
concat()是您发现自己的另一个方便的选择,特别是连接多个值。不过,我建议使用变体concat_ws()(“带分隔符”)以避免尾随空格。
concat_ws(' ', 'Bazzes:', string_agg(b.baz, ', ')) AS bazzes
Run Code Online (Sandbox Code Playgroud)
NULL?NULL如果所有源字段都是NULL(没有非空值,准确地说),则几乎所有聚合函数都返回-count()由于实际原因,这是例外。手册:
需要注意的是,除了 之外
count,当没有选择任何行时,这些函数返回一个空值。特别是,sum没有行返回空值,而不是人们所期望的零,并且array_agg在没有输入行时返回空值而不是空数组。coalesce必要时,该函数可用于将零或空数组替换为 null。
有关的: