sql >> データベース >  >> RDS >> Mysql

すべてのユーザーについて、毎日最高の3つのスコアを選択します

    私のコメントに対するあなたの答えがyesである場合は、次のコードを見てください。 :)あなたのデータはすべて2012年と11月なので、私は1日を取りました。

    クエリ:

    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
    ;
    

    結果:

    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
    

    質問に対する後者の更新に基づきます。ユーザーごとに年/月/日ごとに必要なものがあり、それから最も高いものが見つかった場合は、sumのような集計関数を追加するだけです。 上記のクエリに。サンプルデータは1年間だけなので、年や月ごとのポイントグループはありません。だから私は一日を過ごしました。

    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
    ;
    

    合計に基づく結果:

    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
    

    新しいソースデータサンプルで更新

    サイモン、私自身のサンプルを見てください。あなたのデータが変化していたので、私は私のものを使用しました。これが参考です。純粋なansiを使用しました over partitionのないスタイル またはdense_rank 。また、私が使用したデータは、トップ3のスコアではなくトップ2のスコアを取得していることに注意してください。それに応じて変更できます。

    推測すると、答えは最初のデータが与えた第一印象よりも10倍簡単です...

    SQLFIDDLE

    1にクエリを実行します:-毎日のユーザー別の上位2つの合計について

    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 
    ;
    

    クエリ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
    

    最終クエリ:-2日間すべてのユーザー別の上位2つの合計

    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
    ;
    

    最終結果:

    USERID  SUM(SCORE)
    1      100
    2      47
    3      60
    

    これが私が使用したデータの直接計算のスナップショットです。



    1. phppassword_verifyがデータベースで機能しない

    2. mySQLで640k行を更新しようとすると、クエリ中にMySQLサーバーへの接続が失われます

    3. 配列をoracleプロシージャに渡します

    4. postgresqlのストアドプロシージャを使用してテーブルにデータを挿入する方法