簡體   English   中英

MySQL為每個用戶選擇每組最高的N個分數

[英]Mysql select top N scores per group FOR EACH User

我正在嘗試通過他的高爾夫團隊的“簡單”網站幫助好友。 我要使用的數據庫將存儲每輪比賽結束時所有球員的得分。 還有兩種類型的游戲可以玩和存儲。 下面的例子:

ID        Game Type     Score  
1             a           12
1             a           12
1             a           1
1             a           15
1             a           15
1             b           12
1             b           5
1             b           10
1             b           12
1             b           5
1             b           10
2             a           6
2             a           9
2             a           1
2             a           3 
2             a           2
2             b           8
2             b           10
2             b           15
2             b           3 
2             b           12

我想做的是,為每個用戶選擇A類游戲的前3個得分,並為每個用戶從B類游戲中選擇前2個得分。 我需要選擇才能產生什么,這樣我就可以總結每個球員的得分:

ID        Game Type     Score  
1             a           12
1             a           15
1             a           15
1             b           12
1             b           12

2             a           6
2             a           9
2             a           3 
2             b           15
2             b           12

我在bonCodigo上為每個用戶每天選擇的最高3分找到了類似的問題和解決方案。 我將他的sql更改為此:

-- for top 2 sum by user by each day
SELECT userid, sum(score), type
FROM scores t1
where 3 >=
(SELECT count(*) 
 from scores t2
 where t1.score <= t2.score
 and t1.userid = t2.userid
 and t1.type = t2.type
 order by t2.score desc)
group by userid, type 
;

-- for all two days top 2 sum by user
SELECT userid, sum(score)
FROM scores t1
where 3 >=
(SELECT count(*) 
 from scores t2
 where t1.score <= t2.score
 and t1.userid = t2.userid
 and t1.type = t2.type
 order by t2.score desc)
group by userid
;

我遇到的問題是,如果我想獲得前三名的分數,但是第三名和第四名的分數相等,那么它將不會返回第三名的最高分數; 僅前兩名。 附件是我一直嘗試使用的sqlfiddle。 無論它們是否相等,都對如何使用前3名有任何幫助! 謝謝!

我的sqlfiddle

因此,由於無法放棄這一點,我想出了這種怪異之處,使用存儲過程來獲得所需的輸出(本質上是在應用程序級別復制您要執行的操作以獲得相同的結果)。

create procedure leaderboard()
begin
  declare uid int;
  declare done int default 0;
    declare cur1 cursor for select distinct userid from score;
  declare continue handler for not found set done = 1;
  drop table if exists score_temp;
  create temporary table score_temp(userid int, score int, type int);
  open cur1;
  read_loop: LOOP
    fetch cur1 into uid;
    if done then
      close cur1;
      leave read_loop;
    end if;
    INNERBLOCK: begin
      declare done2 int default 0;       
      declare i_userid int;
      declare i_type int;
      declare i_score int;
      declare cur2 cursor for select * from score where userid = uid and type = 1 order by score desc limit 3;
      declare continue handler for not found set done2 = 1;
      open cur2;
      inner_loop: LOOP
        fetch cur2 into i_userid, i_score, i_type;
        if done2 then
          close cur2;
          leave inner_loop;
        end if;
        insert into score_temp values (i_userid, i_score, i_type);
      end loop inner_loop;
    end INNERBLOCK;
    INNERBLOCK: begin
      declare done2 int default 0;       
      declare i_userid int;
      declare i_type int;
      declare i_score int;
      declare cur2 cursor for select * from score where userid = uid and type = 2 order by score desc limit 2;
      declare continue handler for not found set done2 = 1;
      open cur2;
      inner_loop: LOOP
        fetch cur2 into i_userid, i_score, i_type;
        if done2 then
          close cur2;
          leave inner_loop;
        end if;
        insert into score_temp values (i_userid, i_score, i_type);
      end loop inner_loop;
    end INNERBLOCK;
  end loop read_loop;
  select * from score_temp;
end

然后要獲取排行榜,您的查詢是call leaderboard();

演示小提琴在這里: http ://sqlfiddle.com/#!2/ 569fb2/1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM