1

如果我有

create table t1( attr text primary key, val text );
insert into t1 values( 'attr1', 'val1' );
insert into t1 values( 'attr2', 'val3' );
insert into t1 values( 'attr3', 'val3' );

select返回一排

attr1=>val1, attr2=>val2, attr3=>val3

现在在 javascript 中进行转换,但pg返回行本身会很好


回答

根据@mu 的回答,查询:

select replace( replace( replace( array_agg( hstore( attr, val ) )::text
   '"\"', '"'), 
   '\""', '"'),
   '\"=>\"', '":"')  from t1;

结果是:

{"attr1":"val1","attr2":val2","attr3":"val3"}

这是相当不错的 JSON(只要值中没有引号)

4

2 回答 2

3

我希望它可以array_to_jsonarray_agg. 有关用法,请参阅PostgreSQL 9.2 json 文档,以及支持在 PostgreSQL 9.1 中使用的 JSON 功能直到 9.2 发布的json91模块,或使用 9.2 beta。

不幸的是,事实证明,此时似乎没有任何对合并、聚合等 json 的支持。这使得构建 JSON 值变得异常困难。我只是用常规的文本运算符来做这件事,但这不允许引用问题。

regress=# SELECT '{'||string_agg('"'||attr||'": "'||val||'"', ', ')||'}' FROM t1;
                      ?column?                       
-----------------------------------------------------
 {"attr1": "val1", "attr2": "val3", "attr3": "val3"}
(1 row)

看:

regress=# insert into t1 (attr,val) values ('at"tr', 'v"a"l');
INSERT 0 1
regress=# SELECT '{'||string_agg('"'||attr||'": "'||val||'"', ', ')||'}' FROM t1;
                               ?column?                                
-----------------------------------------------------------------------
 {"attr1": "val1", "attr2": "val3", "attr3": "val3", "at"tr": "v"a"l"}
(1 row)

regress=# SELECT ('{'||string_agg('"'||attr||'": "'||val||'"', ', ')||'}')::json FROM t1;
ERROR:  invalid input syntax for type json
DETAIL:  line 1: Token "tr" is invalid.

您添加到答案中的解决方案中存在相同的问题。为了得到一个好的答案,我们需要类似 的函数json_escape_literal,目前还没有类似的函数暴露给 SQL。

我在 Pg 的当前 json 功能集上看到的唯一安全方法是生成一个对数组,但这并不比使用普通的面向行的查询更好。

regress=# SELECT  array_to_json( array_agg( array_to_json( ARRAY[attr, val] ) )) FROM t1;
                               array_to_json                               
---------------------------------------------------------------------------
 [["attr1","val1"],["attr2","val3"],["attr3","val3"],["at\"tr","v\"a\"l"]]

您可能可以结合使用 hstore 和 json 来做您想做的事,但这就是扩展汤。这真正需要的是一个等效于的 json 对象构造函数,hstore(text[],text[])因此您可以执行以下 json 等效项:

select hstore( array_agg(attr), array_agg(val) ) from t1;

更新关于此主题的 pgsql-general 邮件列表帖子

于 2012-08-05T05:40:26.507 回答
1

如果您安装了hstore,那么您可以使用array_agg

select array_agg(attr => val) from t1;

这将为您提供您正在寻找的输出。当然,无论您使用什么接口都必须了解 hstore 和数组,否则您必须自己解压缩结果;如果是这样的话,迭代一个简单的select attr, val from t1查询并在 JavaScript 中构建数据结构可能会更简单。

于 2012-08-05T04:42:46.793 回答