我想做一些我不太确定的事情。
我从类似的数据库开始:
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');
我希望将数据分组为一个对象,其中common
值为键:
{
"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"}
}
当然,我可以通过多次选择来做到这一点,但单个选择将是有益的。
任何帮助都会很棒!谢谢!
答案 0 :(得分:2)
适用于任何版本的PostgreSQL
这里的重要部分是正确的SELECT
,它可以将数据分组,以便轻松转换为字典类型:
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;
}
有关完整示例,请使用pg-promise:
db.query('SELECT * FROM events GROUP BY common, id ORDER BY common')
.then(data=> {
console.log(transform(data));
})
.catch(error=> {
console.log(error);
});
输出:
{
'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及更高版本,您可以使用函数json_object_agg
在SQL中完成所有操作:
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;
效果比较
比较标准与新方法的表现并不容易,但请考虑一下:
我们有一个简单的单选+非常简单快速的转换,而不是服务器上的双选+双聚合。因此,如果旧的解决方案胜过新的解决方案,我不会感到惊讶。