PostgreSQL将结果集返回为JSON数组?

eng*_*erX 103 postgresql json

我想让PostgreSQL将查询结果作为一个JSON数组返回.特定

create table t (a int primary key, b text);

insert into t values (1, 'value1');
insert into t values (2, 'value2');
insert into t values (3, 'value3');
Run Code Online (Sandbox Code Playgroud)

我想要类似的东西

[{"a":1,"b":"value1"},{"a":2,"b":"value2"},{"a":3,"b":"value3"}]
Run Code Online (Sandbox Code Playgroud)

要么

{"a":[1,2,3], "b":["value1","value2","value3"]}
Run Code Online (Sandbox Code Playgroud)

(实际上,了解两者会更有用).我尝试了一些类似的东西

select row_to_json(row) from (select * from t) row;
select array_agg(row) from (select * from t) row;
select array_to_string(array_agg(row), '') from (select * from t) row;
Run Code Online (Sandbox Code Playgroud)

我觉得我很亲密,但不是真的.除了9.15之外,我应该查看其他文档.JSON函数和操作符

顺便说一句,我不确定我的想法.这是一个通常的设计决定吗?我的想法是,当然,我可以获取上述3个查询中的第一个的结果(例如)并在将其提供给客户端之前在应用程序中稍微操作它,但是如果PostgreSQL可以直接创建最终的JSON对象,它会更简单,因为我还没有在我的应用程序中包含对任何JSON库的依赖.

jpm*_*c26 210

试试这个查询:

SELECT json_agg(t) FROM t
Run Code Online (Sandbox Code Playgroud)

结果是以下JSON:

SELECT
    json_build_object(
        'a', json_agg(t.a),
        'b', json_agg(t.b)
    )
FROM t
Run Code Online (Sandbox Code Playgroud)

这是一个SQLFiddle:http://sqlfiddle.com/#!15/5860d/11/0 .SQLFiddle结果在JSON对象中有一些奇怪json_agg/ jsonb事情,它会转义结果字符串(映射到json_agg),但在普通的PostgreSQL上运行时似乎不会发生这种情况.这似乎是SQLFiddle的一些怪癖.

至于它是否是一个好的设计,实际上取决于你的具体应用.一般来说,基准测试将是判断这在性能方面是否适合您的最佳方式.在可维护性方面,我没有看到任何特殊问题.恰恰相反.它简化了您的应用程序代码,意味着维护更少,至少在我看来.如果PG能够为您提供开箱即用的结果,那么我认为不使用它的唯一原因就是性能方面的考虑.不要重新发明轮子和所有.

编辑:

我没有意识到你正在寻找两个结果的查询.

首先,对于您的第二个结果,您可以使用:

[{"a":1,"b":"value1"},{"a":2,"b":"value2"},{"a":3,"b":"value3"}]
Run Code Online (Sandbox Code Playgroud)

子查询允许您控制生成的JSON对象中的键名.这给了

SELECT json_agg(t) FROM t
Run Code Online (Sandbox Code Playgroud)

SQLFiddle:http://sqlfiddle.com/#!15/5860d/42/0

其次,在我的挖掘中,我发现在9.3中引入了一些你应该考虑的其他功能:

1)json_agg:这就是您想要的第一个结果.

SELECT to_jsonb(array_agg(t)) FROM t
Run Code Online (Sandbox Code Playgroud)

SQLFiddle:http://sqlfiddle.com/#!15/5860d/38/0

2)json_agg:这可以用来代替to_json或者array_to_json给出相同的结果.

SELECT json_agg(t)::jsonb FROM t
Run Code Online (Sandbox Code Playgroud)

SQLFiddle:http://sqlfiddle.com/#!15/5860d/10/0

  • “没有jsonb(9.4中引入)版本的json_agg”:我相信现在有一个jsonb_agg函数 (4认同)
  • 谢谢您的回答.你启发我找到第二个问题的答案,SELECT row_to_json(row(array_agg(ta),array_agg(tb)))FROM t,尽管结果有"f1"和"f2"作为标签而不是a和b. (3认同)
  • 在内部select(从t)返回零行时,在某些情况下可能不希望返回NULL而不是空JSON数组.这是由聚合函数在选择无行并且通过coalesce解决时始终返回NULL引起的:array_to_json(coalesce(array_agg(t),array [] :: record [])). (3认同)
  • 你可以使用`to_json`而不是`row_to_json`和`array_to_json` (3认同)

Him*_*rma 12

此外,如果您希望从表中选择字段并聚合然后作为数组.

SELECT json_agg(json_build_object('data_a',a,
                                  'data_b',b,
))  from t;
Run Code Online (Sandbox Code Playgroud)

结果将来临.

 [{'data_a':1,'data_b':'value1'}
  {'data_a':2,'data_b':'value2'}]
Run Code Online (Sandbox Code Playgroud)


小智 12

对我来说有效

\n
WITH sq AS\n(\n    -- YOUR QUERY HERE \xe2\xac\x87\n    SELECT * \n    FROM "foo" \n    WHERE "id"=\'bar\'\n    -- YOUR QUERY HERE \xe2\xac\x86\n)\nSELECT json_agg(row_to_json(sq)) FROM sq\n
Run Code Online (Sandbox Code Playgroud)\n