MySQL每个用户的第二个最大值

时间:2013-12-13 12:36:49

标签: mysql sql

在MySQL表中有两列:user和score。

如何获得每个用户的第二个最高分数的表格?这些第二个最大值的最大值是什么?

换句话说,我可以拥有这张表:

User | Score
X      50
Y      74
X      9
X      12
Y      21

我想得到一张第二个最大值的表:

User | Score
X    | 12
Y    | 21

另一个最大的第二个最大值:

Score
21

注意:表现很重要。我认为最快的解决方案是正确的。

3 个答案:

答案 0 :(得分:1)

DROP TABLE IF EXISTS scores;

CREATE TABLE scores(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,user CHAR(1) NOT NULL,score INT NOT NULL,INDEX(user,score));

INSERT INTO scores (user,score)
VALUES 
('X',50),
('Y',74),
('X',9),
('X',12),
('Y',21);

SELECT x.* 
  FROM scores x 
  JOIN scores y 
    ON y.user = x.user 
   AND y.score >= x.score 
 GROUP 
    BY x.user
     , x.score 
HAVING COUNT(*) = 2 
 ORDER 
    BY score DESC 
 LIMIT 1;

+----+------+-------+
| id | user | score |
+----+------+-------+
|  5 | Y    |    21 |
+----+------+-------+

如果同一个用户可能有两次相同的分数,那么你可能需要在某处包含一个DISTINCT - 但我会把它作为读者的练习。

如果性能是一个问题,那么类似于以下的解决方案可以无限扩展。我说'相似',因为我习惯在试图跟踪多个变量时变得混乱......

SELECT id,user,score
  FROM
     (
     SELECT id
     , user
     , score
     , @puser := @cuser
     , @prev := @curr
     , @cuser := user
     , @curr := score
     , @rank := IF(@puser = @cuser,IF(@prev = @curr, @rank, @rank+1),@rank:=1) rank
  FROM scores
  JOIN (SELECT @cuser :=null,@puser := null,@curr := null, @prev := null, @rank := 0) sel1
 ORDER 
    BY user, score DESC
    ) x
  WHERE rank = 2
  ORDER BY score DESC LIMIT 1;

+----+------+-------+
| id | user | score |
+----+------+-------+
|  5 | Y    |    21 |
+----+------+-------+

快速测试两个用户的索引表和ca. 10,000行。查询1在15秒内完成,而查询2在1/100秒内完成!

答案 1 :(得分:0)

每个用户没有MAX的所有条目:

SELECT t1.user, t1.score FROM t t1, 
    (SELECT t2.user, t2.score FROM t t2 WHERE t2.score = 
        (SELECT MAX(t3.score) FROM t t3 WHERE t2.user = t3.user)) t4 
WHERE t1.user = t4.user AND t1.score <> t4.score 
GROUP BY t1.user DESC ORDER BY t1.user, t1.score;

只有MAX秒的最大值:

SELECT t1.user, MAX(t1.score) FROM t t1, 
    (SELECT t2.user, t2.score FROM t t2 WHERE t2.score = 
        (SELECT MAX(t3.score) FROM t t3 WHERE t2.user = t3.user)) t4 
WHERE t1.user = t4.user AND t1.score <> t4.score;

SQLFiddle: http://sqlfiddle.com/#!2/f2e717/29

答案 2 :(得分:0)

这将给你第二高分:

SELECT DISTINCT `score` FROM `table_name` ORDER BY `score` DESC LIMIT 1,1

注意:如果你能清楚地了解你的桌子,那对我们非常有帮助。