2017-01-04 17 views
0

4つの列(id、player_id、myDate、points)を持つテーブル(myTable)があるとします。私はすべてのプレイヤーが特定の日に持っていたポイントを見つけたい集計のcolumn1の値の取得(column2)

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

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.

+0

差がかもしれないが、それは、間違いなく、より簡単ですが、実行されるように同じ時間を要する –

+0

私の知る限り、これは確かに速い 'ランク()'と1よりも最速の解決策(とあります大規模ではない)。 – klin

関連する問題