如果我有
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(只要值中没有引号)
答案 0 :(得分:3)
我希望可以将array_to_json
与array_agg
一起使用。请参阅PostgreSQL 9.2 json documentation了解用法,以及json91模块,该模块支持在PostgreSQL 9.1中使用JSON功能,直到9.2用完,或使用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;
答案 1 :(得分:1)