有LIM的替代IN吗?

时间:2011-10-29 17:20:59

标签: mysql

我想实施一个更新游戏中“高分”或“前10名”的程序。

我的想法是执行以下代码:

DELETE FROM Highscore
 WHERE scoreId NOT IN
   (SELECT scoreId FROM Highscore ORDER BY value DESC LIMIT 10)

但后来我收到一个错误,我正在使用的MySQL版本不支持IN LIMIT

还有其他办法吗?

5 个答案:

答案 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 BYLIMIT可以让您进行此类查询。

答案 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”表格上编入索引