将键列和多个值列聚合到JSON对象

时间:2018-12-11 15:16:13

标签: json postgresql aggregate-functions

我有这张桌子:

CREATE TABLE my_table (
    id uuid PRIMARY KEY,
    name text NOT NULL,
    key text NOT NULL,
    x int NOT NULL,
    y int NOT NULL,
    UNIQUE (name, key)
);

使用此数据:

id                                   name key x y
12345678-abcd-1234-abcd-123456789000 foo  a   1 2
12345678-abcd-1234-abcd-123456789001 foo  b   3 4
12345678-abcd-1234-abcd-123456789002 foo  c   5 6
12345678-abcd-1234-abcd-123456789003 foo  d   7 8
12345678-abcd-1234-abcd-123456789004 bar  v   0 0
12345678-abcd-1234-abcd-123456789005 bar  w   1 1
12345678-abcd-1234-abcd-123456789006 bar  z   2 2
12345678-abcd-1234-abcd-123456789007 baz  a   8 7
12345678-abcd-1234-abcd-123456789008 baz  b   6 5
12345678-abcd-1234-abcd-123456789009 baz  c   4 3
12345678-abcd-1234-abcd-123456789010 baz  d   2 1

我有这个查询:

SELECT name, json_build_object(key, json_build_object('x', x, 'y', y))
FROM my_table;

结果如下:

name json_build_object
foo  {"a" : {"x" : 1, "y" : 2}}
foo  {"b" : {"x" : 3, "y" : 4}}
foo  {"c" : {"x" : 5, "y" : 6}}
foo  {"d" : {"x" : 7, "y" : 8}}
bar  {"v" : {"x" : 0, "y" : 0}}
bar  {"w" : {"x" : 1, "y" : 1}}
bar  {"z" : {"x" : 2, "y" : 2}}
baz  {"a" : {"x" : 8, "y" : 7}}
baz  {"b" : {"x" : 6, "y" : 5}}
baz  {"c" : {"x" : 4, "y" : 3}}
baz  {"d" : {"x" : 2, "y" : 1}}

我想要拥有的东西:

foo {"a" : {"x" : 1, "y" : 2}, "b" : {"x" : 3, "y" : 4}, "c" : {"x" : 5, "y" : 6}, "d" : {"x" : 7, "y" : 8}}
bar {"v" : {"x" : 0, "y" : 0}, "w" : {"x" : 1, "y" : 1}, "z" : {"x" : 2, "y" : 2}}
baz {"a" : {"x" : 8, "y" : 7}, "b" : {"x" : 6, "y" : 5}, "c" : {"x" : 4, "y" : 3}, "d" : {"x" : 2, "y" : 1}}

我知道我需要另外GROUP BY nameaggregate列,但是找不到functions的合适组合。单个查询是否有可能?

1 个答案:

答案 0 :(得分:2)

您的查询应为:

SELECT 
    name, 
    json_object_agg(key, json_build_object('x', x, 'y', y)) 
FROM data
GROUP BY name

demo:db<>fiddle

json_object_agg正是您想要的。