任何可以解释我如何选择的SQL专家都会说出前三项。当第3项等于第4项和第5项时,我也喜欢那些,但仅限于那种情况。例如以下列表
40,
30,
15,
15,
15,
10
它会返回40,30,15,15,15而不是40,30,15。
答案 0 :(得分:1)
如果您只想输出得分字段,可以这样做:
SET @ranks = 3;
PREPARE stmt_top3 FROM
'SELECT score FROM (
SELECT score, (@row := @row + 1), IF (@row = ?, @min_score := score, NULL)
FROM user_score
WHERE score IN (
SELECT top_score.score FROM (
SELECT DISTINCT score,
(@row := 0), (@min_score := 0)
FROM user_score
ORDER BY score DESC
LIMIT ?
) AS top_score
)
ORDER BY score DESC
) AS score_rows
WHERE score >= @min_score
ORDER BY score DESC';
EXECUTE stmt_top3 USING @ranks, @ranks;
DEMO @ SQL Fiddle
我使用了准备好的声明,因此显示的排名数量是灵活的。如果您不想要,只需硬编码3
而不是2 ?
。
否则,如果您还需要排名和user_id,即这里有更广泛的方法:
高分排名(共享排名)
选择共享第一个排名的所有行,无论有多少行。 只要这些行的数量不大于或等于允许的最大等级(在您的示例中为3),下一个等级就是行数+ 1。 一切都从一开始就等等......
SET @ranks = 3;
PREPARE stmt_top3 FROM
'SELECT user_score.user_id, score_rank.rank, score_rank.score
FROM user_score
INNER JOIN (
SELECT (@last_rank := @last_rank + @last_equal_score) AS rank,
score, (@last_equal_score := count(score)) AS equal_score
FROM user_score
WHERE score IN (
SELECT top_score.score FROM (
SELECT DISTINCT score,
(@last_rank := 1), (@last_equal_score := 0)
FROM user_score
ORDER BY score DESC
LIMIT ?
) AS top_score
)
GROUP BY score
ORDER BY score DESC
) AS score_rank
ON user_score.score = score_rank.score
WHERE score_rank.rank <= ?
ORDER BY score_rank.rank ASC';
EXECUTE stmt_top3 USING @ranks, @ranks;
DEMO @ SQL Fiddle
由于MySQL在某些子查询运算符(如LIMIT
)的子查询中不支持IN
,因此必须在另一个简单子查询中包含包含LIMIT
子句的子查询避免以下错误:
ERROR 1235(42000):这个版本的MySQL还没有支持&#39; LIMIT &安培; IN / ALL / ANY / SOME子查询&#39;
我使用以下设置进行测试:
CREATE TABLE user (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY
) ENGINE=InnoDB;
INSERT INTO user (id) VALUES
(NULL),
(NULL),
(NULL),
(NULL),
(NULL),
(NULL);
CREATE TABLE user_score (
user_id INT UNSIGNED NOT NULL UNIQUE,
score INT NOT NULL DEFAULT 0,
INDEX (score),
FOREIGN KEY (user_id) REFERENCES user (id)
) ENGINE=InnoDB;
INSERT INTO user_score (user_id, score) VALUES
(1, 40),
(2, 30),
(3, 15),
(4, 15),
(5, 15),
(6, 10);
答案 1 :(得分:1)
SELECT *
FROM myTable
WHERE Field1 IN(
SELECT *
FROM (
SELECT DISTINCT Field1
FROM myTable
ORDER BY Field1 DESC
LIMIT 3)
) t
你可能从你的例子中得到的唯一问题是,如果你特别想要包含40&amp; D的复制品。 30?