PostgreSQL:为每个独特的种族选择第二低的值?
PostgreSQL: Selecting second lowest value for each unique race?
我有以下 table 使用 PostgreSQL
ID
racedate
racetime
racename
track
horsename
pos
weight
1
2022-1-1
01:00
race1
test
MrEd
1
56
2
2022-1-1
01:00
race1
test
SeaBiscuit
2
54
3
2022-1-1
01:00
race1
test
Frankel
3
51
4
2022-1-1
02:00
race2
test
SeaRose
1
57
2
2022-1-1
02:00
race2
test
WarAdmiral
2
65
等等。当然还有更多的列和行。
现在我想select每场比赛体重的第二低值。
所以我只想为数据库中的每场独特比赛获得一个结果 - 我该怎么做?
我尝试了 MIN() 和 LEAST() 的变体,例如
SELECT DISTINCT ON (races.id) races.id, MIN( weight ), horses.horsename, races.racename, races.racedate, races.track
FROM horses
RIGHT JOIN races ON races.racedate = horses.racedate AND races.racetime = horses.racetime AND races.racename = horses.racename AND races.track = horses.track
WHERE weight > ( SELECT MIN( weight )
FROM horses )
GROUP BY races.id, weight, horses.horsename, races.racename, races.racedate, races.track
ORDER BY races.id, weight
但这给了我最低的价值——不是第二低的。
racedate+racetime+track+racename 是唯一的,一起是主键,我后来加了ID。
谢谢大家的帮助!
此处使用DENSE_RANK
:
WITH cte AS (
SELECT r.id, h.weight, h.horsename, r.racename, r.racedate, r.track,
DENSE_RANK() OVER (PARTITION BY r.racename ORDER BY h.weight) drnk
FROM races r
LEFT JOIN horses h
ON r.racedate = h.racedate AND
r.racetime = h.racetime AND
r.racename = h.racename AND
r.track = h.track
)
SELECT id, weight, horsename, racename, racedate, track
FROM cte
WHERE drnk = 2;
请注意,RANK()
或 ROW_NUMBER()
在这里也可能有意义,具体取决于您的要求。
我有以下 table 使用 PostgreSQL
ID | racedate | racetime | racename | track | horsename | pos | weight |
---|---|---|---|---|---|---|---|
1 | 2022-1-1 | 01:00 | race1 | test | MrEd | 1 | 56 |
2 | 2022-1-1 | 01:00 | race1 | test | SeaBiscuit | 2 | 54 |
3 | 2022-1-1 | 01:00 | race1 | test | Frankel | 3 | 51 |
4 | 2022-1-1 | 02:00 | race2 | test | SeaRose | 1 | 57 |
2 | 2022-1-1 | 02:00 | race2 | test | WarAdmiral | 2 | 65 |
等等。当然还有更多的列和行。
现在我想select每场比赛体重的第二低值。 所以我只想为数据库中的每场独特比赛获得一个结果 - 我该怎么做?
我尝试了 MIN() 和 LEAST() 的变体,例如
SELECT DISTINCT ON (races.id) races.id, MIN( weight ), horses.horsename, races.racename, races.racedate, races.track
FROM horses
RIGHT JOIN races ON races.racedate = horses.racedate AND races.racetime = horses.racetime AND races.racename = horses.racename AND races.track = horses.track
WHERE weight > ( SELECT MIN( weight )
FROM horses )
GROUP BY races.id, weight, horses.horsename, races.racename, races.racedate, races.track
ORDER BY races.id, weight
但这给了我最低的价值——不是第二低的。
racedate+racetime+track+racename 是唯一的,一起是主键,我后来加了ID。
谢谢大家的帮助!
此处使用DENSE_RANK
:
WITH cte AS (
SELECT r.id, h.weight, h.horsename, r.racename, r.racedate, r.track,
DENSE_RANK() OVER (PARTITION BY r.racename ORDER BY h.weight) drnk
FROM races r
LEFT JOIN horses h
ON r.racedate = h.racedate AND
r.racetime = h.racetime AND
r.racename = h.racename AND
r.track = h.track
)
SELECT id, weight, horsename, racename, racedate, track
FROM cte
WHERE drnk = 2;
请注意,RANK()
或 ROW_NUMBER()
在这里也可能有意义,具体取决于您的要求。