代码之家  ›  专栏  ›  技术社区  ›  relet

避免在PostgreSQL 8.3.4中嵌套聚合函数

  •  1
  • relet  · 技术社区  · 14 年前

    假设我的 subquery avg(abs(x-mean)/y) mean 实际上是 avg(x)

    select avg(abs(x-avg(x))/y) as incline from subquery 失败,因为我无法嵌套聚合函数。我也没有办法在保留原始结果集的同时计算子查询中的平均值。一个avgdev函数,因为它存在于其他方言中,并不能完全帮助我,所以我被困在这里。可能只是因为缺乏sql知识-在后处理中从结果集计算值很容易。

    哪个SQL构造可以帮助我?

    编辑:服务器版本为8.3.4。没有窗口功能 WITH OVER 这里有。

    3 回复  |  直到 14 年前
        1
  •  1
  •   a_horse_with_no_name    14 年前

    我不确定我是否正确理解你,但你可能在寻找这样的东西:

    SELECT avg(x - mean/y)
    FROM (
      SELECT x, 
             y, 
             avg(x) as mean over(partition by your_grouping_column) 
      FROM your_table
    ) t
    

    如果您不需要对结果进行分组以获得正确的平均值(x),那么只需使用一个空over省略“partition by”: over()

        2
  •  1
  •   user533832 user533832    13 年前

    如果数据集不是太大,可以将它们累积到一个数组中,然后从函数返回斜面:

    create type typ as (x numeric, y numeric);
    
    create aggregate array_accum( sfunc = array_append,
                                  basetype = anyelement,
                                  stype = anyarray,
                                  initcond = '{}' );
    
    create or replace function unnest(anyarray) returns setof anyelement 
                               language sql immutable strict as $$
      select $1[i] from generate_series(array_lower($1,1), array_upper($1,1)) i;$$;
    
    create function get_incline(typ[]) returns numeric 
                    language sql immutable strict as $$
      select avg(abs(x-(select avg(x) from unnest($1)))/y) from unnest($1);$$;
    
    select get_incline((select array_accum((x,y)::typ) from subquery));
    

    create view subquery as 
    select generate_series(1,5) as x, generate_series(1,6) as y;
    
        3
  •  0
  •   relet    14 年前

    我发现的一个选项是使用临时表:

    begin; 
      create temporary table sub on commit drop as (...subquery code...);
      select avg(abs(x-mean)/y) as incline from (SELECT x, y, (SELECT avg(x) FROM sub) AS mean FROM sub) as sub2;
    commit;
    

    但这是不是太过分了?