create aggregate two_elements(anyelement) ( sfunc = array_limit_two, stype = anyarray, initcond = '{}' ); create or replace function array_limit_two(anyarray, anyelement) returns anyarray as $$ begin if array_upper($1,1) = 2 then return $1; else return array_append($1, $2); end if; end; $$ language 'plpgsql';
Get the data here: How to find the second best grade of a student?
Then this...
select student, two_elements(grade order by grade desc) from student_grades group by student;
...will return(two best grades of a student):
student | two_elements ---------+-------------- george | {40} john | {100,90} paul | {50,30}
To return the second best grades only, use this:
select student, array_min( two_elements(grade order by grade desc) ) from student_grades group by student;
Here's the array_min function:
create or replace function array_min(anyarray) returns anyelement as $$ select min(unnested) from( select unnest($1) unnested ) as x $$ language sql;
student | array_min ---------+----------- george | 40 john | 90 paul | 30 (3 rows)
I think this code is more performant than the previous one
Wisdom of the day:
Unless you actually are going to solve the general problem, don't try and put in place a framework for solving a specific one, because you don't know what that framework should look like.
Wisdom source: http://tirania.org/blog/archive/2003/Sep-29.html
No comments:
Post a Comment