获取column1的值为aggregate(column2)

时间:2017-01-04 21:40:15

标签: postgresql aggregate-functions

假设我有一个包含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

是否有更好(=更有效)的方式来实现我想要的目标?

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;

Test it here.