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;