Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wählen Sie die höchsten 3 Punktzahlen an jedem Tag für jeden Benutzer aus

Bitte werfen Sie einen Blick auf den folgenden Code, wenn Ihre Antwort auf meinen Kommentar yes ist :) Da Ihre Daten alle im Jahr 2012 und Monat November sind, habe ich Tag genommen.

Abfrage:

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
;

Ergebnisse:

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

Basierend auf Ihren letzten Aktualisierungen zur Frage. Wenn Sie einige pro Benutzer nach Jahr/Monat/Tag benötigen und dann den höchsten finden, können Sie einfach eine Aggregationsfunktion wie sum hinzufügen zu obiger Abfrage. Ich wiederhole mich, da Ihre Beispieldaten nur für ein Jahr gelten, gibt es keine Punktgruppe nach Jahr oder Monat. Deshalb habe ich Tag genommen.

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
;

Ergebnisse basierend auf Summe:

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

AKTUALISIERT MIT NEUEM QUELLDATENBEISPIEL

Simon, schau dir bitte mein eigenes Beispiel an. Da sich Ihre Daten geändert haben, habe ich meine verwendet. Hier ist die Referenz. Ich habe reines ansi verwendet Stil ohne over partition oder dense_rank . Beachten Sie auch, dass die von mir verwendeten Daten Top-2- und nicht Top-3-Ergebnisse erzielen. Sie können es entsprechend ändern.

Stellen Sie sich vor, die Antwort ist 10-mal einfacher als der erste Eindruck, den Ihre ersten Daten vermitteln...

SQLFIDDLE

Abfrage zu 1:-- für die Top-2-Summe nach Benutzer pro Tag

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 
;

Ergebnisse für Abfrage 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

Abschließende Abfrage:-- für alle zwei Tage Top-2-Summe nach Benutzer

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
;

Endergebnisse:

USERID  SUM(SCORE)
1      100
2      47
3      60

Hier ist eine Momentaufnahme der direkten Berechnungen der von mir verwendeten Daten.