【问题标题】:Get an average value for element in column of arrays of json data in postgres获取postgres中json数据数组列中元素的平均值
【发布时间】:2014-08-27 16:07:08
【问题描述】:

我在 postgres 表中有一些数据,它是 json 数据数组的字符串表示形式,如下所示:

[
  {"UsageInfo"=>"P-1008366", "Role"=>"Abstract", "RetailPrice"=>2, "EffectivePrice"=>0},
  {"Role"=>"Text", "ProjectCode"=>"", "PublicationCode"=>"", "RetailPrice"=>2},  
  {"Role"=>"Abstract", "RetailPrice"=>2, "EffectivePrice"=>0, "ParentItemId"=>"396487"}
]

这是我数据库中单列相似数据的一个单元格中的数据。

这个存储在db中的数据类型是varchar(max)。

我的目标是找到每个带有“Role”=>“Abstract”的 json 项目的平均零售价格,包括数组中的所有 json 元素以及数据库中的所有行。

类似:

SELECT avg(json_extract_path_text(json_item, 'RetailPrice'))
FROM (
  SELECT cast(json_items to varchar[]) as json_item
  FROM my_table
  WHERE json_extract_path_text(json_item, 'Role') like 'Abstract'
)

现在,由于某些原因,这个特定的查询显然无法正常工作。 Postgres 不允许您直接将 varchar 转换为 varchar[]。即使在我有一个数组之后,这个查询也不会对数组进行迭代。它可能还有其他问题,但我希望它有助于澄清我想要得到什么。

关于如何从数据库中所有这些 json 数据数组中获取平均零售价的任何建议?

【问题讨论】:

标签: sql arrays json postgresql amazon-redshift


【解决方案1】:

Redshift 本身似乎不支持json 数据类型。至少,I found nothing in the online manual.

不过我找了几个JSON function in the manual,应该是有帮助的:

JSON_ARRAY_LENGTH 
JSON_EXTRACT_ARRAY_ELEMENT_TEXT
JSON_EXTRACT_PATH_TEXT

由于不支持generate_series(),我们必须替换它...

SELECT tbl_id
     , round(avg((json_extract_path_text(elem, 'RetailPrice'))::numeric), 2) AS avg_retail_price
FROM   (
   SELECT *, json_extract_array_element_text(json_items, pos) AS elem
   FROM  (VALUES (0),(1),(2),(3),(4),(5)) a(pos)
   CROSS JOIN tbl
   ) sub
WHERE  json_extract_path_text(elem, 'Role') = 'Abstract'
GROUP  BY 1;
  • 我用穷人的解决方案代替:一个从 0 到 n 的虚拟表(VALUES 表达式)。确保计算到数组中可能元素的最大数量。如果您需要定期创建一个实际的numbers 表。

  • 现代 Postgres 有更好的选择,比如 json_array_elements() 可以取消嵌套 json 数组。与 Postgres 的兄弟问题比较:

我在 Postgres 中使用 related operator ->> 进行了测试,它可以工作:
SQL Fiddle.

【讨论】:

    猜你喜欢
    • 2022-01-20
    • 1970-01-01
    • 2018-02-25
    • 1970-01-01
    • 2020-05-28
    • 1970-01-01
    • 1970-01-01
    • 2013-12-29
    • 1970-01-01
    相关资源
    最近更新 更多