我如何 return 来自 jsonb 的对象数组?
How do I return an array of objects from jsonb?
我有以下 table:
CREATE TABLE mytable (
id serial PRIMARY KEY
, employee text UNIQUE NOT NULL
, data jsonb
);
具有以下数据:
INSERT INTO mytable (employee, data)
VALUES
('Jim', '{"sales_tv": [{"value": 10, "yr": "2010", "loc": "us"}, {"value": 5, "yr": "2011", "loc": "europe"}, {"value": 40, "yr": "2012", "loc": "asia"}], "sales_radio": [{"value": 11, "yr": "2010", "loc": "us"}, {"value": 8, "yr": "2011", "loc": "china"}, {"value": 76, "yr": "2012", "loc": "us"}], "another_key": "another value"}'),
('Rob', '{"sales_radio": [{"value": 7, "yr": "2014", "loc": "japan"}, {"value": 3, "yr": "2009", "loc": "us"}, {"value": 37, "yr": "2011", "loc": "us"}], "sales_tv": [{"value": 4, "yr": "2010", "loc": "us"}, {"value": 18, "yr": "2011", "loc": "europe"}, {"value": 28, "yr": "2012", "loc": "asia"}], "another_key": "another value"}')
请注意,除了 "sales_tv" 和 "sales_radio" 之外,还有其他键。对于下面的查询,我只需要关注 "sales_tv" 和 "sales_radio".
我正在尝试 return 为吉姆创建一个以 "sales_" 开头的对象列表。在每个对象 w/in 列表中,我只需要 return 值和年份(忽略 "location" 或任何其他键)例如:
employee | sales_
Jim | {"sales_tv": [{"value": 10, "yr": "2010"}, {"value": 5, "yr": "2011"}, {"value": 40, "yr": "2012"}],
"sales_radio": [{"value": 11, "yr": "2010"}, {"value": 8, "yr": "2011"}, {"value": 76, "yr": "2012"}]}
我能够获取每个值,但没有年份,也没有我想要的列表格式:
SELECT t.employee, json_object_agg(a.k, d.value) AS sales
FROM mytable t
, jsonb_each(t.data) a(k,v)
, jsonb_to_recordset(a.v) d(yr text, value float)
WHERE t.employee = 'Jim'
AND a.k LIKE 'sales_%'
GROUP BY 1
结果:
employee | sales
---------- | --------
Jim | { "sales_tv" : 10, "sales_tv" : 5, "sales_tv" : 40, "sales_radio" : 11, "sales_radio" : 8, "sales_radio" : 76 }
原理同,第一个查询(虽然本题是昨天的第二个查询):把你的json
数据层层剥离,然后重新assemble 将它与您感兴趣的任何数据一起转换成任何新的 json
格式。
SELECT employee, json_object_agg(k, jarr) AS sales
FROM (
SELECT t.employee, a.k,
json_agg(json_build_object('value', d.value, 'yr', d.yr)) AS jarr
FROM mytable t,
jsonb_each(t.data) a(k, v),
jsonb_to_recordset(a.v) d(yr text, value float)
WHERE t.employee = 'Jim'
AND a.k like 'sales_%'
GROUP BY 1, 2) sub
GROUP BY 1;
在 FROM
子句中,您使用 jsonb_each
和 jsonb_to_recordset
等函数分解了 JSON 层次结构。正如最后一个函数的名称所暗示的那样,其中的每一个都会生成一组记录,您可以像处理任何其他 table 及其列一样处理这些记录。在列 selection 中列出了您 select 所需的数据和适当的聚合函数 json_agg
和 json_object_agg
以将 JSON 结果拼凑起来。对于层次结构的每一层,您都需要一个聚合函数,因此需要一个子查询层。
我有以下 table:
CREATE TABLE mytable (
id serial PRIMARY KEY
, employee text UNIQUE NOT NULL
, data jsonb
);
具有以下数据:
INSERT INTO mytable (employee, data)
VALUES
('Jim', '{"sales_tv": [{"value": 10, "yr": "2010", "loc": "us"}, {"value": 5, "yr": "2011", "loc": "europe"}, {"value": 40, "yr": "2012", "loc": "asia"}], "sales_radio": [{"value": 11, "yr": "2010", "loc": "us"}, {"value": 8, "yr": "2011", "loc": "china"}, {"value": 76, "yr": "2012", "loc": "us"}], "another_key": "another value"}'),
('Rob', '{"sales_radio": [{"value": 7, "yr": "2014", "loc": "japan"}, {"value": 3, "yr": "2009", "loc": "us"}, {"value": 37, "yr": "2011", "loc": "us"}], "sales_tv": [{"value": 4, "yr": "2010", "loc": "us"}, {"value": 18, "yr": "2011", "loc": "europe"}, {"value": 28, "yr": "2012", "loc": "asia"}], "another_key": "another value"}')
请注意,除了 "sales_tv" 和 "sales_radio" 之外,还有其他键。对于下面的查询,我只需要关注 "sales_tv" 和 "sales_radio".
我正在尝试 return 为吉姆创建一个以 "sales_" 开头的对象列表。在每个对象 w/in 列表中,我只需要 return 值和年份(忽略 "location" 或任何其他键)例如:
employee | sales_
Jim | {"sales_tv": [{"value": 10, "yr": "2010"}, {"value": 5, "yr": "2011"}, {"value": 40, "yr": "2012"}],
"sales_radio": [{"value": 11, "yr": "2010"}, {"value": 8, "yr": "2011"}, {"value": 76, "yr": "2012"}]}
我能够获取每个值,但没有年份,也没有我想要的列表格式:
SELECT t.employee, json_object_agg(a.k, d.value) AS sales
FROM mytable t
, jsonb_each(t.data) a(k,v)
, jsonb_to_recordset(a.v) d(yr text, value float)
WHERE t.employee = 'Jim'
AND a.k LIKE 'sales_%'
GROUP BY 1
结果:
employee | sales
---------- | --------
Jim | { "sales_tv" : 10, "sales_tv" : 5, "sales_tv" : 40, "sales_radio" : 11, "sales_radio" : 8, "sales_radio" : 76 }
原理同json
数据层层剥离,然后重新assemble 将它与您感兴趣的任何数据一起转换成任何新的 json
格式。
SELECT employee, json_object_agg(k, jarr) AS sales
FROM (
SELECT t.employee, a.k,
json_agg(json_build_object('value', d.value, 'yr', d.yr)) AS jarr
FROM mytable t,
jsonb_each(t.data) a(k, v),
jsonb_to_recordset(a.v) d(yr text, value float)
WHERE t.employee = 'Jim'
AND a.k like 'sales_%'
GROUP BY 1, 2) sub
GROUP BY 1;
在 FROM
子句中,您使用 jsonb_each
和 jsonb_to_recordset
等函数分解了 JSON 层次结构。正如最后一个函数的名称所暗示的那样,其中的每一个都会生成一组记录,您可以像处理任何其他 table 及其列一样处理这些记录。在列 selection 中列出了您 select 所需的数据和适当的聚合函数 json_agg
和 json_object_agg
以将 JSON 结果拼凑起来。对于层次结构的每一层,您都需要一个聚合函数,因此需要一个子查询层。