Setup
I have a table of race times, listing a runner, their team, and their race time:
CREATE TABLE race (person TEXT, team TEXT, timer FLOAT);
INSERT INTO race
(person, team, timer)
VALUES
("ahmed", "red", 4.3),
("baadur", "green", 4.4),
("carel", "red", 4.5),
("dada", "green", 4.9),
("eder", "green", 5.0),
("farai", "red", 5.1);
I can make a list of all people on the red team and their ranking:
SELECT person, ROW_NUMBER() OVER(ORDER BY timer) AS ranking FROM race WHERE team="red";
which emits
person | ranking |
---|---|
ahmed | 1 |
carel | 2 |
farai | 3 |
Question
I want to also get the name of runner who followed each of these red runners, i.e., who had the next slowest time—so I want:
person | ranking | next runner |
---|---|---|
ahmed | 1 | baadur |
carel | 2 | dada |
farai | 3 | null |
where note how since nobody has a slower time than Farai, Farai's third column is null.
Can I do this efficiently with a single query?
Considerations
I'd like to avoid first getting the list of red runners and their times with one query and then making another three (or more generally N
) queries to get the runner with the next time, e.g., this is what I do not want to do:
SELECT person FROM race WHERE timer>=4.3 AND person != "ahmed" LIMIT 1;
SELECT person FROM race WHERE timer>=4.5 AND person != "carel" LIMIT 1;
SELECT person FROM race WHERE timer>=5.1 AND person != "farai" LIMIT 1;
--