Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Selecione as 3 pontuações mais altas em cada dia para cada usuário


Por favor, dê uma olhada no código a seguir, se sua resposta ao meu comentário for yes :) Desde seus dados todos em 2012, e mês de novembro, tirei dia.

Inquerir:
select y.id, y.userid, y.score, y.datestamp 
from (select id, userid, score, datestamp 
      from scores
      group by day(datestamp)) as y    
where (select count(*) 
       from (select id, userid, score, datestamp
             from scores group by day(datestamp)) as x
       where y.score >= x.score
       and y.userid = x.userid
      ) =1 -- Top 3rd, 2nd, 1st    
order by y.score desc
;

Resultados:
ID  USERID  SCORE   DATESTAMP
8   2       8.5 December, 07 2012 00:00:00+0000
20  3       6   December, 08 2012 00:00:00+0000
1   1       5   December, 06 2012 00:00:00+0000

Com base em suas últimas atualizações para question.Se você precisar de alguns por usuário por ano/mês/dia e depois encontrar o mais alto, você pode simplesmente adicionar uma função de agregação como sum para a consulta acima. Estou me repetindo, já que seus dados de amostra são de apenas um ano, não há grupo de pontos por ano ou mês. Por isso tirei o dia.
select y.id, y.userid, y.score, y.datestamp 
from (select id, userid, sum(score) as score,
      datestamp 
from scores
group by userid, day(datestamp)) as y    
where (select count(*) 
from (select id, userid, sum(score) as score
      , datestamp
from scores
group by userid, day(datestamp)) as x
where y.score >= x.score
and y.userid = x.userid
) =1 -- Top 3rd, 2nd, 1st    
order by y.score desc
;

Resultados com base na soma:
ID  USERID  SCORE   DATESTAMP
1   1       47.5    December, 06 2012 00:00:00+0000
8   2       16      December, 07 2012 00:00:00+0000
20  3       6       December, 08 2012 00:00:00+0000

ATUALIZADO COM NOVA AMOSTRA DE DADOS DE FONTE


Simon, por favor, dê uma olhada na minha própria amostra. Como seus dados foram mudando, usei os meus. Aqui está a referência. Eu usei ansi puro estilo sem qualquer over partition ou dense_rank .Observe também que os dados que usei estão obtendo as pontuações do top 2 e não do top 3. Você pode mudar é em conformidade.

Adivinhe, a resposta é 10 vezes mais simples do que a primeira impressão que seus primeiros dados deram...

SQLFIDDLE


Consulta para 1:-- para a soma dos 2 principais por usuário a cada dia
SELECT userid, sum(Score), datestamp
FROM scores t1
where 2 >=
(SELECT count(*) 
 from scores t2
 where t1.score <= t2.score
 and t1.userid = t2.userid
 and day(t1.datestamp) = day(t2.datestamp)
 order by t2.score desc)
group by userid, datestamp 
;

Resultados para a consulta 1:
USERID  SUM(SCORE)  DATESTAMP
1       70      December, 06 2012 00:00:00+0000
1       30      December, 07 2012 00:00:00+0000
2       22      December, 06 2012 00:00:00+0000
2       25      December, 07 2012 00:00:00+0000
3       30      December, 06 2012 00:00:00+0000
3       30      December, 07 2012 00:00:00+0000

Consulta final:-- para todos os dois dias da soma dos 2 primeiros por usuário
SELECT userid, sum(Score)
FROM scores t1
where 2 >=
(SELECT count(*) 
 from scores t2
 where t1.score <= t2.score
 and t1.userid = t2.userid
 and day(t1.datestamp) = day(t2.datestamp)
 order by t2.score desc)
group by userid
;

Resultados finais:
USERID  SUM(SCORE)
1      100
2      47
3      60

Aqui vai um instantâneo de cálculos diretos de dados que usei.