假设我有一个包含4列(id,player_id,myDate,points)的表(myTable)。我想找到所有球员在某一天所拥有的分数
id | player_id | myDate | points
------ | --------- | ---------- | -----
1 | 1 | 2016-05-06 | 50
2 | 1 | 2016-10-16 | 60
3 | 1 | 2016-09-12 | 70
4 | 1 | 2016-09-16 | 30
5 | 2 | 2016-02-05 | 10
6 | 2 | 2016-10-18 | 20
7 | 2 | 2017-01-02 | 30
8 | 2 | 2016-08-16 | 40
2017年1月1日的预期结果:
id | player_id | myDate | points
------ | --------- | ---------- | -----
2 | 1 | 2016-10-16 | 60
6 | 2 | 2016-10-18 | 20
到目前为止我会做的事情如下:(首先找到每个玩家的最后日期,然后是该日期的得分)
select id, q.player_id, points from
(
select player_id, max(myDate) as maxDate from myTable
where myDate<'2017-01-01'
group by player_id
) q
left join myTable
on q.maxDate=myTable.mydate
and q.player_id=myTable.player_id
当然,如果我在同一天有同一个玩家的2条记录,我会为这个player_id获得2行,我将不得不在查询中添加更多代码来解决这个问题。
除此之外,我必须自我加入(我的表目前有1.000.000条记录 - 这是一个观点),这可能不会很快。
我最近一直在使用另一个查询:
select id,player_id,points from
(
select rank() over
(partition by player_id
order by myDate desc, id desc) as r, *
from myTable
where myDate <'2017-01-01'
) q
where r=1
是否有更好(=更有效)的方式来实现我想要的目标?
答案 0 :(得分:1)
使用DISTINCT ON
。
select distinct on (player_id) *
from my_table
where my_date < '2017-01-01'
order by player_id, my_date desc;