【问题标题】:Calculating a normalized average with Rails using Postgres JSON column使用 Postgres JSON 列使用 Rails 计算归一化平均值
【发布时间】:2015-09-01 14:08:48
【问题描述】:

我在 Postgres 数据库中有一个大型统计表,其中架构如下所示:

player_id: integer,
region: string,
position: string,
league: string,
stats: json

我使用this blog post 构建了以下查询,以查找 stats json 对象中给定属性的平均值(以“命中”统计信息为例):

attributes = {region: 'x', position: 'y', league: 'z'}
Stat.where(attributes).average("cast(payload ->> 'hits' as integer)").to_f

效果很好,而且速度很快。然而,一些统计数据需要根据玩家在游戏中的时间来构建。给定一个具有以下格式的 stats 对象:

{
  "kills":10
  "time_played":120 # seconds
}

我希望获得每分钟 5 次击杀的值 (10 / (120/60))简单的例子...)

在这里,我很困惑。我知道 sql 划分东西没有问题,但是把 JSON 扔进去让我很困惑。我试过这个:

Stat.where(attributes).average("cast(payload ->> 'kills' as integer) / (cast(payload ->> 'time_played' as integer) / 60)").to_f

它返回0 - 我不确定如何调试这个语句。有任何想法吗?

解决方案

在 EgonWilzer 的帮助下,这最终奏效了:

def query_for(stat, per_minute: false)
  base = "cast(payload ->> '#{stat}' as float)"

  return base unless per_minute
  base + " / (cast(payload ->> 'time_played' as float) / 60)"
end

【问题讨论】:

  • 问题可能是除法整数/整数,如果第二个更大,它总是返回0。也许你可以用as real代替as integer试试?
  • 好主意,@EgonWilzer,但不会改变输出。
  • 我把它收回 - 我有一个错误(没有将 time_played 位除以 60!),这似乎确实有效 - 如果您将其添加为答案,我会很乐意接受它。干杯

标签: sql ruby-on-rails json postgresql


【解决方案1】:

问题是除法整数/整数,如果第二个更大,它总是返回0。

使用as real 而不是as integer,您可能会得到预期的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-06
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    • 1970-01-01
    • 2013-02-19
    相关资源
    最近更新 更多