关于postgres的一个好处是它allows indexing into a json object。
我有一列数据格式有点像这样:
{"Items":
[
{"RetailPrice":6.1,"EffectivePrice":0,"Multiplier":1,"ItemId":"53636"},
{"RetailPrice":0.47,"EffectivePrice":0,"Multiplier":1,"ItemId":"53404"}
]
}
我想要做的是找到包含这些数据的每行的平均RetailPrice。
像
这样的东西select avg(json_extract_path_text(item_json, 'RetailPrice'))
但实际上我需要为json对象中的每个项目执行此操作。因此,对于此示例,查询的单元格中的值将为3.285
我该怎么做?
答案 0 :(得分:3)
可以像这样工作:
WITH cte(tbl_id, json_items) AS (
SELECT 1
, '{"Items": [
{"RetailPrice":6.1,"EffectivePrice":0,"Multiplier":1,"ItemId":"53636"}
,{"RetailPrice":0.47,"EffectivePrice":0,"Multiplier":1,"ItemId":"53404"}]}'::json
)
SELECT tbl_id, round(avg((elem->>'RetailPrice')::numeric), 3) AS avg_retail_price
FROM cte c
, json_array_elements(c.json_items->'Items') elem
GROUP BY 1;
CTE只是替代了一个表:
CREATE TABLE tbl (
tbl_id serial PRIMARY KEY
, json_items json
);
json_array_elements()
(Postgres 9.3+)取消json
阵列是有用的。
我在这里使用隐式JOIN LATERAL
。与此相关示例非常相似:
对于支持此类查询的索引,请考虑以下相关答案:
有关如何最好地存储EAV data的详细信息: