Reputation: 397
I have the following table:
id | date | gap |
---|---|---|
1 | 2020-01-01 | 3 |
2 | 2020-01-01 | 5 |
3 | 2020-01-01 | 8 |
4 | 2020-01-02 | 6 |
5 | 2020-01-02 | 10 |
6 | 2020-01-02 | 12 |
I want to iterate over the distinct dates and fetch the two rows with the highest "gap" value. Desired result:
id | date | gap |
---|---|---|
2 | 2020-01-01 | 5 |
3 | 2020-01-01 | 8 |
5 | 2020-01-02 | 10 |
6 | 2020-01-02 | 12 |
I have attempted the following
DO $$
DECLARE
temprow record;
BEGIN
FOR temprow in
SELECT DISTINCT date
FROM table
LOOP
SELECT *
FROM table
ORDER BY gap DESC
LIMIT 2;
END LOOP;
END;
$$;
Giving me the following error:
ERROR: query has no destination for result data.
Wrapping the last SELECT statement with a RETURN() gives:
ERROR: RETURN cannot have a parameter in function returning void
I am not sure if I even need a loop for this, so feel free to suggest a solution without a loop.
Upvotes: 1
Views: 844
Reputation: 13049
You do not need a loop nor plpgsql for this.
select l.* from
(
select distinct "date" as dd from the_table
) t
cross join lateral
(
select * from the_table
where "date" = t.dd order by gap desc limit 2
) l
order by "date", gap;
Almost in plain language - for every distinct date dd
fetch two rows.
Upvotes: 2
Reputation:
This can be done using window functions:
select id, "date", gap
from (
select id, "date", gap,
dense_rank() over (partition by "date" order by gap desc) as rnk
from the_table
) t
where rnk <= 2
order by "date", gap;
If there are two rows with the same (highest) gap on the same date, both will be returned. If you don't want that, use row_number()
instead of dense_rank()
Upvotes: 3