Sql 多维数组输出为JSON
我想做一些我不完全确定是否可行的事情 我从一个类似以下内容的数据库开始:Sql 多维数组输出为JSON,sql,postgresql,Sql,Postgresql,我想做一些我不完全确定是否可行的事情 我从一个类似以下内容的数据库开始: create table events (id int primary key, common int, location text); insert into events values (2, 100, 'Something'); insert into events values (3, 100, 'Something'); insert into events values (4, 100, 'Something
create table events (id int primary key, common int, location text);
insert into events values (2, 100, 'Something');
insert into events values (3, 100, 'Something');
insert into events values (4, 100, 'Something');
insert into events values (5, 200, 'Something');
insert into events values (6, 200, 'Something');
insert into events values (7, 200, 'Something');
insert into events values (8, 200, 'Something');
insert into events values (9, 100, 'Something');
insert into events values (10, 200, 'Something');
insert into events values (11, 200, 'Something');
insert into events values (12, 200, 'Something');
insert into events values (13, 300, 'Something');
insert into events values (14, 200, 'Something');
insert into events values (15, 300, 'Something');
insert into events values (16, 200, 'Something');
insert into events values (17, 300, 'Something');
我想将数据分组到一个对象中,对象的公共值作为键:
{
"100":{
"2":"Something",
"3":"Something",
"4":"Something",
"9":"Something"},
"200":{
"5":"Something",
"6":"Something",
"7":"Something",
"8":"Something"},
"300":{
"13":"Something",
"15":"Something",
"17":"Something",
"18":"Something"}
}
当然,我可以通过多次选择来实现,但是一次选择是有益的
任何帮助都会很棒!谢谢 适用于任何版本的PostgreSQL
这里最重要的部分是正确的选择
,它可以对数据进行分组,从而使数据易于转换为字典类型:
SELECT * FROM events GROUP BY common, id ORDER BY common
它产生以下输出:
2 100 "Something"
3 100 "Something"
4 100 "Something"
9 100 "Something"
5 200 "Something"
6 200 "Something"
7 200 "Something"
8 200 "Something"
10 200 "Something"
11 200 "Something"
12 200 "Something"
14 200 "Something"
16 200 "Something"
13 300 "Something"
15 300 "Something"
17 300 "Something"
此时,无论服务器端代码使用何种语言,将其转换为带有common
的字典都是一项简单的任务
例如,在Node.js中,您可以这样做:
function transform(rows) {
var key, obj, result = {};
rows.forEach(function (r) {
if (r.common !== key) {
if (obj) {
result[key] = obj;
}
obj = {};
key = r.common;
}
obj[r.id] = r.location;
});
if (obj) {
result[key] = obj;
}
return result;
}
有关完整示例,请使用:
产出:
{
'100': {
'2': 'Something',
'3': 'Something',
'4': 'Something',
'9': 'Something'
},
'200': {
'5': 'Something',
'6': 'Something',
'7': 'Something',
'8': 'Something',
'10': 'Something',
'11': 'Something',
'12': 'Something',
'14': 'Something',
'16': 'Something'
},
'300': {
'13': 'Something',
'15': 'Something',
'17': 'Something'
}
}
适用于PostgreSQL 9.4及更高版本
使用PostgreSQL 9.4及更高版本,您可以在SQL中使用函数json\u object\u agg
:
SELECT json_object_agg(common, j ORDER BY common)
FROM (SELECT common, json_object_agg(id, location order by id)
AS j FROM events GROUP BY common) t;
性能比较
比较标准与新方法的性能并不容易,但请考虑如下:
我们有一个简单的单选择+一个非常简单和快速的转换,而不是服务器上的双选择+双聚合。因此,如果旧的解决方案优于新的解决方案,我不会感到惊讶。是的,我认为这是最好的方法,感谢代码:D我用PHP编写,所以代码不是我想要的,但我很确定我可以翻译它。谢谢
SELECT json_object_agg(common, j ORDER BY common)
FROM (SELECT common, json_object_agg(id, location order by id)
AS j FROM events GROUP BY common) t;