简体   繁体   中英

Group by by two columns and find average of another in PostgreSQL

I have a problem with the function where I need to group by two columns and take an average of another.

Why the following won't work?

CREATE OR REPLACE FUNCTION core.cal_average_load(
  cell_load      DOUBLE PRECISION,
  id           DOUBLE PRECISION,
  s_id          DOUBLE PRECISION
) RETURNS DOUBLE PRECISION
  LANGUAGE plpgsql
AS $$
DECLARE out DOUBLE PRECISION;
  BEGIN
    out := (AVG(cell_load) OVER (PARTITION BY id, s_id));
  RETURN out;
  END;
$$;

The above return me just average_load value exactly the same as cell_load value, without any aggregation.

id    s_id   cell_load   average_load
1      1        4             6
1      1        2             6
1      1        12            6
1      2        3             4
1      2        5             4
2      1        10            4.33
2      1        1             4.33
2      2        2             3.66
2      2        3             3.66
2      2        6             3.66

You are calling the function for a single row. Using a window function makes sense only for a dataset with multiple rows. I do not think you need a function at all, example:

with my_table(id, s_id, cell_load) as (
values
    (1, 1, 1),
    (1, 1, 2),
    (1, 2, 3),
    (1, 2, 4),
    (1, 2, 5)
)

select id, s_id, avg(cell_load) over (partition by id, s_id)
from my_table;

 id | s_id |        avg         
----+------+--------------------
  1 |    1 | 1.5000000000000000
  1 |    1 | 1.5000000000000000
  1 |    2 | 4.0000000000000000
  1 |    2 | 4.0000000000000000
  1 |    2 | 4.0000000000000000
(5 rows)

or:

select id, s_id, avg(cell_load)
from my_table
group by 1, 2;

 id | s_id |        avg         
----+------+--------------------
  1 |    1 | 1.5000000000000000
  1 |    2 | 4.0000000000000000
(2 rows)    

If the function is necessary it should look like this:

create or replace function cal_average_load(
    _id double precision,
    _s_id double precision)
returns double precision
language sql as $$
    select avg(cell_load)
    from my_table
    where id = _id and s_id = _s_id
$$;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM