sql >> Base de Datos >  >> RDS >> Mysql

Seleccione los 3 puntajes más altos en cada día para cada usuario

Eche un vistazo al siguiente código, si su respuesta a mi comentario es yes :) Dado que todos sus datos en 2012 y el mes de noviembre, tomé el día.

Consulta:

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

Basado en sus últimas actualizaciones a la pregunta. Si necesita algunos por usuario por año/mes/día y luego encuentra el más alto, simplemente puede agregar una función de agregación como sum a la consulta anterior. Me vuelvo a repetir, dado que los datos de muestra son de solo un año, no hay un grupo de puntos por año o mes. Por eso tomé el día.

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 basados ​​en la suma:

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

ACTUALIZADO CON UNA NUEVA MUESTRA DE DATOS DE FUENTE

Simon, echa un vistazo a mi propia muestra. Como sus datos estaban cambiando, usé los míos. Aquí está la referencia. He usado puro ansi estilo sin ninguna over partition o dense_rank .También tenga en cuenta que los datos que utilicé obtienen las 2 mejores puntuaciones, no las 3 mejores. Puede cambiar en consecuencia.

Adivina qué, la respuesta es 10 veces más simple que la primera impresión que dieron tus primeros datos....

SQLFIDDLE

Consulta a 1:-- para la suma de los 2 principales por usuario cada día

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 de la 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 los dos días, la suma de los 2 principales por usuario

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 finales:

USERID  SUM(SCORE)
1      100
2      47
3      60

Aquí va una instantánea de los cálculos directos de los datos que utilicé.