我正在使用Postgres 9.2来生成一些JSON数据。对于每个嵌套表,我都在做这个嵌套的函数集:
SELECT array_to_json(
coalesce(
array_agg(
row_to_json(foo)),
ARRAY[]::json[])
)
FROM foo
效果是创建一个json数组,每行都是该行的json集合。如果表为空,coalesce确保我得到一个空数组而不是nil。在大多数情况下,foo实际上是一个子查询,但我不认为这与问题相关。
我想创建一个函数 table_to_json_array(expression),以便它具有与上面相同的效果:
SELECT table_to_json_array(foo) FROM foo
我需要使用这些批次,所以我打算创建一个Postgres函数,以便将这些调用组合起来清理我的查询。看看文档,似乎我需要创建一个聚合而不是一个函数来获取一个表参数,但看起来我需要重新实现 array_agg 。
我错过了什么(可能只是一个函数需要的类型)?有什么建议吗?
答案 0 :(得分:2)
在大多数情况下,foo实际上是一个子查询,但我认为不是 相关问题。
不幸的是,确实如此。您可以使用 regclass 参数创建一个函数:
create or replace function table_to_json(source regclass)
returns json language plpgsql
as $$
declare
t json;
begin
execute format ('
SELECT
array_to_json(
coalesce(array_agg(row_to_json(%s)),
ARRAY[]::json[]))
FROM %s', source, source)
into t;
return t;
end $$;
select table_to_json('my_table');
select table_to_json('my_schema.my_view');
但在上下文中:
select table_to_json_rec(arg)
from (select * from my_table) arg
参数 arg 的类型为记录。 PL / pgSQL函数不能接受类型记录。得到这个的唯一方法是C函数,我想这不是一个选项。聚合也是如此(您必须具有定义聚合的函数)。
答案 1 :(得分:1)
Postgres 9.3增加了一个 json_agg 函数,它简化了我需要的特定查询,尽管这不是聚合函数问题的一般解决方案。它仍然需要 coalesce 函数来确保正确返回空集。
SELECT coalesce( json_agg(foo), json'[]')
FROM foo
即使 foo 是子查询,它也能正常工作。