【发布时间】:2022-01-12 04:12:57
【问题描述】:
设置
我有一张比赛时间表,列出了跑步者、他们的团队和他们的比赛时间:
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);
我可以列出红色团队中的所有人及其排名:
SELECT person, ROW_NUMBER() OVER(ORDER BY timer) AS ranking FROM race WHERE team="red";
会发光
| person | ranking |
|---|---|
| ahmed | 1 |
| carel | 2 |
| farai | 3 |
问题
我还想获得跟随这些红色跑步者中的每一个的跑步者的名字,即,谁的时间第二慢——所以我想要:
| person | ranking | next runner |
|---|---|---|
| ahmed | 1 | baadur |
| carel | 2 | dada |
| farai | 3 | null |
请注意,由于没有人比 Farai 的时间慢,Farai 的第三列是空的。
我可以通过单个查询有效地做到这一点吗?
注意事项
我想避免首先通过一个查询获取红色跑步者的列表及其时间,然后再进行另外三个(或更一般地N)查询以获取下一次跑步者,例如,这就是我确实不想做:
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;
-- ????
我也许可以将上述方法重新设计为单个查询而不是多个单独的查询,但我觉得如果有办法为每个查询运行子查询,应该可以在单个查询中得到我想要的与WHERE team="red" 子句匹配的行以查找下一行(可以通过timer 上的索引来快速查找),但我不确定这是否可能。
例如,我可以使用 SQLite 的lag 窗口函数来实现吗? lag 本身会查看符合我的 WHERE team="red" 标准的行,因此如果他们在绿队或其他非红队,它不会返回下一个最慢的跑步者。
这种查询有通用术语吗?
可能有许多团队和许多跑步者,所以我想知道如何使这种查找尽可能高效。
【问题讨论】: