【问题标题】:Calculate average from JSON column从 JSON 列计算平均值
【发布时间】:2015-02-06 17:05:25
【问题描述】:

我有一个表,其中有一列 JSON 数据,我想从中提取信息。具体来说,我只想得到平均值。

我所拥有的示例:

id      speed_data
391982  [{"speed":1.3,"speed":1.3,"speed":1.4,"speed":1.5...
391983  [{"speed":0.9,"speed":0.8,"speed":0.8,"speed":1.0...

我想要的示例:

id      speed_data
391982  1.375
391982  0.875

关于如何使这个查询起作用的任何建议?

select t.*, avg(x.speed)
from tbl t,
    json_array_elements(a->'speed') x
order by random()
limit 1

【问题讨论】:

  • 你得到了什么结果?您的值是否正在转换为整数?
  • 您将无法执行此操作。你有语义上无效的 json:在一个 json 对象中,每个键只能出现一次;此 json 在语法上是有效的,但只有最后一对(带有键 "speed")会在结果中看到(解析后)。

标签: sql json postgresql types aggregate-functions


【解决方案1】:

你的 json 数组搞砸了,比如@posz commented。必须是:

CREATE TABLE tbl (id int, speed_data json);

INSERT INTO tbl VALUES
  (391982, '{"speed":[1.3,1.3,1.4,1.5]}')
, (391983, '{"speed":[0.9,0.8,0.8,1.0]}');

您的查询也以多种方式扭曲。在 pg 9.3 中会这样工作:

SELECT t.id, avg(x::text::numeric) AS avg_speed
FROM   tbl t
     , json_array_elements(speed_data->'speed') x
GROUP  BY t.id;

SQL Fiddle.

在即将到来的 pg 9.4 中,我们可以使用新的 json_array_elements_text() 进行简化(在演员表中也不太容易出错):

SELECT t.id, avg(x::numeric) AS avg_speed
FROM   tbl t
     , json_array_elements_text(speed_data->'speed') x
GROUP  BY t.id;

更多详情:

另外:将其存储为普通数组(numeric[],而不是json)或以规范化模式开始会更有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-14
    • 2012-07-12
    • 1970-01-01
    相关资源
    最近更新 更多