我遇到了“postgres”SQL问题。
我有一张看起来像这样的桌子
id name level timestamp 1 pete 1 100 2 pete 1 200 3 pete 1 500 4 pete 5 900 7 pete 5 1000 9 pete 5 1200 15 pete 2 700
现在我想删除我不需要的行。我现在只想要他获得新等级的第一行,以及他拥有这个等级的最后一行。
id name level timestamp 1 pete 1 100 3 pete 1 500 15 pete 2 700 4 pete 5 900 9 pete 5 1200
(还有更多列,如realmpoints等)
如果时间戳只是增加,我有一个解决方案。
SELECT id, name, level, timestamp
FROM player_testing
WHERE id IN ( SELECT MAX(dup.id)
FROM player_testing As dup
GROUP BY dup.name, dup.level)
UNION
SELECT MIN(dup.id)
FROM player_testing As dup
GROUP BY dup.name, dup.level)
)
ORDER BY ts
但我发现无法让它解决我的问题。
答案 0 :(得分:2)
select id, name, level, timestamp
from (
select id,name,level,timestamp,
row_number() over (partition by name, level order by timestamp) as rn,
count(*) over (partition by name, level) as max_rn
from player_testing
) t
where rn = 1 or rn = max_rn;
顺便说一下:timestamp
是一个可怕的名字。出于一个原因,因为它是一个保留字,但更重要的是因为它没有记录列包含的内容。这是start_timestamp
和end_timestamp
一个valid_until_timestamp
,......?
答案 1 :(得分:0)
这是@ a_horse_with_no_name没有over partition
的替代解决方案,因此更通用的SQL:
select *
from player_testing as A
where id = (
select min(id)
from player_testing as B
where A.name = B.name
and A.level = B.level
)
or id = (
select max(id)
from player_testing as B
where A.name = B.name
and A.level = B.level
)
这是表明它有效的小提琴:http://sqlfiddle.com/#!2/47bd44/1