我正在尝试找到前 5 名跑完 1km
的运行者,但如果满足该条件的运行者少于 5 名,则将 km
递增1 直到满足 LIMIT
5。
唯一需要注意的是,如果在递增 km
时发现 2 个或更多结果,则应返回具有更高 score
的结果,即使另一个结果有降低 km_run
。
最终的结果集应该按照分数排序。
运行者
id runner km_run score
1 mary 3.5 0.55
2 anna 1.5 0.95
3 john 6.5 0.90
4 bill 1.5 0.15
5 jess 6.2 0.35
6 jack 2.5 0.75
我尝试使用子查询首先返回按score
排序的表,然后在外部查询上放置一个LIMIT
。
SELECT runner, km_run, score
FROM runners
WHERE runner IN
(SELECT runner FROM runners
ORDER BY score DESC)
ORDER BY km_run LIMIT 5
但这只会返回 km
最低的 5 位运行者。
相反,我想要的正是这个:
id runner km_run score
2 anna 1.5 0.95
3 john 6.5 0.90
6 jack 2.5 0.75
1 mary 3.5 0.55
5 jess 6.2 0.35
请注意以下几点:
- 结果按分数降序排列
- 返回 ID 3 和 5 但不返回 ID 4
这是因为在 6-7 km
间隔之前只有 4/5 的结果被发现,然后发现了 2 个结果。这两个结果的得分均高于 ID 4,因此将其纳入。
Between Results
0-1 km 0
1-2 km 2
2-3 km 1
3-4 km 1 --> here we have 4/5 results required
4-5 km 0
5-6 km 0
6-7 km 2 --> now we have 6, but we only want the 5 w/ best score
设置查询:
CREATE TABLE runners(
id SERIAL,
runner VARCHAR,
km_run DECIMAL,
score DECIMAL,
PRIMARY KEY (id)
);
INSERT INTO runners (runner, km_run, score)
VALUES ('mary', 3.5, 0.55);
INSERT INTO runners (runner, km_run, score)
VALUES ('anna', 1.5, 0.95);
INSERT INTO runners (runner, km_run, score)
VALUES ('john', 6.5, 0.90);
INSERT INTO runners (runner, km_run, score)
VALUES ('bill', 1.5, 0.15);
INSERT INTO runners (runner, km_run, score)
VALUES ('jess', 6.2, 0.35);
INSERT INTO runners (runner, km_run, score)
VALUES ('jack', 2.5, 0.75);
最佳答案
首先获取所有排名 5 或更高的运行者,其中排名基于截断的 km_run
。然后获得得分最高的 5 个。
在 SQL 中:
SELECT runner, km_run, score
FROM (SELECT runner, km_run, score,
rank() OVER (ORDER BY floor(km_run))
FROM runners) AS q
WHERE rank <= 5
ORDER BY score DESC
LIMIT 5;
runner | km_run | score
--------+--------+-------
anna | 1.5 | 0.95
john | 6.5 | 0.90
jack | 2.5 | 0.75
mary | 3.5 | 0.55
jess | 6.2 | 0.35
(5 rows)
查询效率不是很高,因为它必须扫描整个runners
表。但这很难根据您的要求避免——我们需要扫描多少表行并不清楚。
关于postgresql - 增加查询参数直到达到 LIMIT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55997722/