【问题标题】:Postgres (Amazon RDS) how to calculate weighted averagePostgres(Amazon RDS)如何计算加权平均值
【发布时间】:2016-04-07 04:54:54
【问题描述】:

我正在使用 Amazon RDS Postgres 数据库 (9.4.4),我想计算一些数据的加权平均值。

我找到了以下看起来非常适合这项工作的扩展程序。 https://github.com/Kozea/weighted_mean

但是我现在不确定如何安装扩展,因为我最初的研究表明只允许“支持”的扩展。

http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html#PostgreSQL.Concepts.General.FeatureSupport

我有什么选择来使用这个扩展。我不想重新发明轮子,而且我不熟悉在 Postgres 中安装任何类型的功能/扩展。

谢谢

【问题讨论】:

    标签: postgresql amazon-rds postgresql-9.4


    【解决方案1】:

    为什么你不发出这样的简单查询:

    select 
      case when sum(quantity) = 0 then 
       0 
      else 
       sum(unitprice * quantity) / sum(quantity) 
      end 
    from sales;
    

    当然您需要更改字段(单价、数量)

    【讨论】:

    • 确实是 RDS 的解决方案
    • 您可以通过使用NULLIFCOALESCE: COALESCE(sum(unitprice * quantity) / NULLIF(sum(quantity) , 0), 0) 来避免CASE 和重复的SUM。我不确定这那个好得多,但我一点也不喜欢CASE声明。
    【解决方案2】:

    SUM(value*weight)/SUM(weight) 答案很好,但如果您需要不断重复使用它,创建聚合函数会更方便。

    CREATE FUNCTION avg_weighted_step(state numeric[], value numeric, weight numeric)
    RETURNS numeric[]
    LANGUAGE plpgsql
    AS $$
    BEGIN
        RETURN array[state[1] + value*weight, state[2] + weight];
    END;
    $$ IMMUTABLE;
    
    
    CREATE FUNCTION avg_weighted_finalizer(state numeric[])
    RETURNS numeric
    LANGUAGE plpgsql
    AS $$
    BEGIN
        IF state[2] = 0 THEN
            RETURN null;
        END IF;
        RETURN state[1]/state[2];
    END;
    $$ IMMUTABLE;
    
    
    CREATE AGGREGATE avg_weighted(value numeric, weight numeric) (
        sfunc = avg_weighted_step, 
        stype = numeric[],
        finalfunc = avg_weighted_finalizer,
        initcond = '{0,0}' );
    

    示例用法:

    $ table tmp;
    v  w 
    -- -
     1 2
    10 1
    (2 rows)
    
    $ select avg_weighted(v, w) from tmp;
       avg_weighted    
    ------------------
    4.0000000000000000
    (1 row)
    
    $ select avg_weighted(v, w) from tmp where v is null;
    avg_weighted 
    ------------
               ∅
    (1 row)
    

    【讨论】:

    • 太棒了!和 AWS RDS 兼容!,(我的解决方案与你的几乎相同。我使用“sql”而不是“plpgsql”)。
    【解决方案3】:

    为了注册新的自定义扩展,您需要将适当的脚本添加到 Postgres 安装的 contrib 目录。 AWS 不允许您拥有如此精细的控制。

    长话短说,您无法将任何自定义扩展(除了您提供的linkpg_available_extensions 视图中指定的扩展)添加到Amazon RDS 服务。

    这是使用 DBaaS(数据库即服务)解决方案的缺点之一。

    【讨论】:

    • 谢谢,我是 DBaaS 的忠实粉丝,但我想没有完美的解决方案。
    猜你喜欢
    • 2021-11-24
    • 2010-10-04
    • 1970-01-01
    • 2017-01-06
    • 2016-05-10
    • 2015-04-02
    • 2012-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多