Mysql 有没有一种方法可以替代带限制的IN?

Mysql 有没有一种方法可以替代带限制的IN?,mysql,Mysql,我想实现一个更新游戏中高分或前10名分数的过程 我的想法是执行以下代码: 从Highscore删除 scoreId不在哪里 按值DESC LIMIT 10从Highscore ORDER中选择scoreId 但是我得到一个错误,我使用的MySQL版本不支持限制 还有其他方法吗?可以使用更新现有行,而不是插入新行 另一种方法是编辑获得高分的select。这样,你也可以记录所有以前的高分。使用ORDER BY和LIMIT可以执行此类查询。您可以使用更新现有行,而不是插入新行 另一种方法是编辑获得高分

我想实现一个更新游戏中高分或前10名分数的过程

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

从Highscore删除 scoreId不在哪里 按值DESC LIMIT 10从Highscore ORDER中选择scoreId 但是我得到一个错误,我使用的MySQL版本不支持限制


还有其他方法吗?

可以使用更新现有行,而不是插入新行


另一种方法是编辑获得高分的select。这样,你也可以记录所有以前的高分。使用ORDER BY和LIMIT可以执行此类查询。

您可以使用更新现有行,而不是插入新行


另一种方法是编辑获得高分的select。这样,你也可以记录所有以前的高分。使用ORDER BY和LIMIT可以进行这样的查询。

我没有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;

我没有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;
最后的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

最后的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个。

另一种解决方法:

DELETE FROM Highscore
WHERE scoreId NOT IN
   (SELECT scoreId FROM Highscore ORDER BY value DESC LIMIT 10)
是将子查询与另一个子查询中的限制括在一起:

DELETE FROM Highscore
WHERE scoreId NOT IN
   (SELECT scoreId FROM 
      (SELECT scoreId FROM Highscore ORDER BY value DESC LIMIT 10)
      AS tmp
   )
但我认为最好不要在WHERE子句中将嵌套子查询与要从中删除的同一个表的引用结合起来。我认为最好使用“加入”:

或者更好,如果您可以使用值索引使其更简单、可能更快,因为在您的案例中可能会注意到,如果第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

另一个解决方法是:

DELETE FROM Highscore
WHERE scoreId NOT IN
   (SELECT scoreId FROM Highscore ORDER BY value DESC LIMIT 10)
是将子查询与另一个子查询中的限制括在一起:

DELETE FROM Highscore
WHERE scoreId NOT IN
   (SELECT scoreId FROM 
      (SELECT scoreId FROM Highscore ORDER BY value DESC LIMIT 10)
      AS tmp
   )
但我认为最好不要在WHERE子句中将嵌套子查询与要从中删除的同一个表的引用结合起来。我认为最好使用“加入”:

或者更好,如果您可以使用值索引使其更简单、可能更快,因为在您的案例中可能会注意到,如果第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
试试这个

首先,创建前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”表中编入索引

试试这个

首先,创建前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”表中编入索引

r你确定要回答这个问题吗?更新?mhnm?得分最低的那一排?我认为那不是个好主意。如果游戏结束,所有人的分数将发送到数据库,人数是可变的。所以我不知道如何使用更新在这种情况下,你可以使用删除限制,但不能OFFSET@ypercube我的回答中没有提到偏移量?@Marcus:LIMIT x,y与LIMIT y OFFSET x相同。你确定要回答这个问题吗?更新?mhnm?得分最低的那一排?我认为那不是个好主意。如果游戏结束,所有人的分数将发送到数据库,人数是可变的。所以我不知道如何使用更新在这种情况下,你可以使用删除限制,但不能OFFSET@ypercube我在回答中没有提到偏移量?@Marcus:LIMIT x,y与LIMIT y OFFSET x相同。mysql不允许在内部查询中使用top/LIMIT。@itaymav是认真的吗?我会把这个放在这里,以防其他服务器需要它。我们都是mysql用户
pe此问题很快就会得到解决,但遗憾的是,最新版本中可能会出现这种情况。它已存在,但不确定它们的生产是否稳定。子查询中不允许使用限制:在\ALL\ANY\SOME子查询中使用限制。在其他子查询中是允许的。mysql不允许在内部查询中使用top/limit。@ItayMov认真吗?我将把它留在这里,以防其他服务器需要它。我们所有mysql用户都希望它能很快得到修复,但遗憾的是,这种情况可能是在最新版本中开始出现的。它存在,但不确定它们的生产是否稳定。子查询中不允许使用限制:在\ALL\ANY\SOME子查询中使用限制。这在其他子查询中是允许的。SET@tmp=从Highscore按值顺序选择值描述限制10,1从Highscore删除,其中值<@tmp是的,但如果11行的值与行10SET@tmp=从Highscore按值顺序选择值描述限制10,1从Highscore删除,其中值<@tmp是的,这会有点问题可以工作,但如果11行的值与第10行的值相同,则会有一点问题