我想实施一个更新游戏中“高分”或“前10名”的程序。
我的想法是执行以下代码:
DELETE FROM Highscore
WHERE scoreId NOT IN
(SELECT scoreId FROM Highscore ORDER BY value DESC LIMIT 10)
但后来我收到一个错误,我正在使用的MySQL版本不支持IN
LIMIT
。
还有其他办法吗?
答案 0 :(得分:3)
DELETE FROM Highscore ORDER BY value DESC LIMIT 10,5
最后5
可以是任何数字。如果您每次添加分数时都运行此分数,则可以将其设为1
。要允许更多误差,请使用10
。
DELETE FROM Highscore WHERE value < (SELECT value FROM Highscore ORDER BY value DESC LIMIT 10,1)
如果它不允许你这样做(从同一个表中选择更新/删除),请尝试:
SET @tmp = (SELECT value FROM Highscore ORDER BY value DESC LIMIT 10,1)
DELETE FROM Highscore WHERE value < @tmp
再次编辑:正如评论中指出的那样,如果第11个值等于10,则会导致问题。尝试:
SET @id = (SELECT scoreId FROM Highscore ORDER BY value DESC, scoreId DESC LIMIT 10,1), @val = (SELECT value FROM Highscore ORDER BY value DESC LIMIT 10,1)
DELETE FROM Highscore WHERE value <= @val AND scoreId < @id
在第一个变量中按scoreId排序可确保当有多个具有相同分数时,将留下不少于10个。
答案 1 :(得分:2)
另一种解决方法:
DELETE FROM Highscore
WHERE scoreId NOT IN
(SELECT scoreId FROM Highscore ORDER BY value DESC LIMIT 10)
将子查询与LIMIT
括在另一个子查询中:
DELETE FROM Highscore
WHERE scoreId NOT IN
(SELECT scoreId FROM
(SELECT scoreId FROM Highscore ORDER BY value DESC LIMIT 10)
AS tmp
)
但我认为最好不要将嵌套子查询与WHERE
子句中的引用组合到要删除的同一个表中。我认为最好使用JOIN
:
DELETE h
FROM
Highscore AS h
CROSS JOIN
( SELECT scoreId FROM Highscore ORDER BY value DESC LIMIT 10
) AS tmp
WHERE h.scoreId NOT IN (SELECT scoreId FROM tmp)
甚至更好,如果你可以使它更简单(并且可能在value
上有更快的索引),因为在你的情况下是可能的(注意如果有关系,以下将保持超过10行在第10位):
DELETE h
FROM
Highscore AS h
CROSS JOIN
( SELECT value
FROM Highscore
ORDER BY value DESC
LIMIT 1 OFFSET 9
) AS tmp
WHERE h.value < tmp.value
答案 2 :(得分:1)
您可以使用UPDATE
更新现有行,而不是插入新行。
另一种方法是编辑获得高分的选择。这样你就可以跟踪所有以前的高分。使用ORDER BY
和LIMIT
可以让您进行此类查询。
答案 3 :(得分:0)
我没有MySQL安装来测试它,但在TSQL中你可以做类似的事情
delete from HighSchore
where scoreID not in
(select top 10 scoreID from HighScore order by Value desc)
当然,最好使用外连接而不是子查询来执行此操作。
此外,在我看来,你永远不应该删除这样的数据,但只要你需要就可以检索前10名。
select top 10 value
from Highscore
order by Value desc;
答案 4 :(得分:0)
试试这个。
首先,创建前10名临时表
CREATE TEMPORARY TABLE tmp_highscores
(SELECT scoreId FROM Highscore ORDER BY value DESC LIMIT 10);
然后,删除那些不在前10名
DELETE FROM Highscore WHERE scoreId NOT IN
(SELECT scoreId FROM tmp_highscores)
并且,不要忘记:“scoreId”应该在“Highscore”表格上编入索引