sql >> Databasteknik >  >> RDS >> Mysql

Välj högsta 3 poäng varje dag för varje användare

Ta en titt på följande kod om ditt svar på min kommentar är yes :) Eftersom dina uppgifter allt under 2012, och november månad, tog jag dag.

Fråga:

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
;

Resultat:

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

Baserat på dina senare uppdateringar av frågan. Om du behöver några per användare per år/månad/dag och sedan hittar högst, kan du helt enkelt lägga till en aggregeringsfunktion som sum till ovanstående fråga. Jag upprepar mig själv, eftersom dina exempeldata är för bara ett år, finns det ingen poäng grupp efter år eller månad. Det var därför jag tog dagen.

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
;

Resultat baserat på summa:

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

UPPDATERAD MED NYTT KÄLLDATAPROV

Simon, ta en titt på mitt eget prov. Eftersom dina uppgifter förändrades använde jag min. Här är referensen. Jag har använt ren ansi stil utan någon over partition eller dense_rank Observera också att de uppgifter jag använde får topp 2 inte topp 3 poäng. Du kan ändra är därefter.

Gissa vad, svaret är 10 gånger enklare än det första intrycket din första data gav...

SQLFIDDLE

Fråga till 1:-- för topp 2 summa per användare per dag

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 
;

Resultat för fråga 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

Slutlig fråga:-- för alla två dagar topp 2 summa av användare

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
;

Slutresultat:

USERID  SUM(SCORE)
1      100
2      47
3      60

Här kommer en ögonblicksbild av direkta beräkningar av data jag använde.



  1. 2 sätt att returnera rader som inte innehåller numeriska värden i Oracle

  2. Lägg till ny kolumn till resultat- och sammansmältningstabellen

  3. Hur man väljer en rad baserat på maxvärdet i flera rader

  4. Hur ON CONFLICT fungerar i SQLite