【问题标题】:Delete all but the 50 newest rows删除除 50 个最新行之外的所有行
【发布时间】:2010-09-13 21:01:56
【问题描述】:

我有一个包含新闻报道和 Unix 时间戳的 SQL 表。我只想保留 50 个最新的故事。如何编写 SQL 语句来删除任何数量的旧故事?

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    我刚刚这样做了:

    DELETE FROM `table` WHERE `datetime` < (SELECT `datetime` FROM `table` ORDER BY `datetime` DESC LIMIT 49,1);

    table 是表格,datetime 是日期时间字段。

    【讨论】:

      【解决方案2】:

      嗯,看起来你不能在一个查询中做到这一点 - 如果我错了,请有人纠正我。我曾经能够做这种事情的唯一方法是首先弄清楚表中的行数。例如:

      select count(*) from table;
      

      然后使用结果做

      delete from table order by timestamp limit result - 50;
      

      你必须这样做有两个原因 -

      1. MySQL 5 不支持删除子查询的限制
      2. MySQL 5 不允许您从要从中删除的同一个表中选择子查询。

      【讨论】:

        【解决方案3】:

        块引用

        delete from table where id not in (
            select id from table 
            order by id desc 
            limit 50
        )
        

        您选择您不想删除的数据的 ID,然后删除所有不在这些值中的内容...

        【讨论】:

        • 这假设您有顺序 ID,这通常是一个公平的假设。如果不这样做,则需要使用数据库中的时间戳或其他顺序字段来执行此操作
        • 似乎不起作用,只是得到错误:#1235 - 此版本的 MySQL 尚不支持 'LIMIT & IN/ALL/ANY/SOME 子查询'
        • 子查询肯定应该是“从表中选择 id”,而不是“从表中选择 *”?
        • @Gilean 你应该调整这个查询,看看你的 mysql 版本支持什么样的命令。这只是您的问题的输入...
        • MySQL 5 中的子查询似乎不支持 LIMIT
        【解决方案4】:

        我最终使用了两个查询,因为 MySQL5 还不支持 LIMIT 的子查询

        SELECT unixTime FROM entries ORDER BY unixTime DESC LIMIT 49, 1;
        DELETE FROM entries WHERE unixTime < $sqlResult;
        

        【讨论】:

          【解决方案5】:

          如果您有很多行,最好将这 50 行放在一个临时表中 然后使用 TRUNCATE TABLE 清空表。然后将 50 行放回原处。

          【讨论】:

          • 截断重置自动递增计数器 - 因此,如果您的 ID 处于自动递增状态,您需要在截断表后修改自动递增的下一个值,以便下一个 ID 出现在最大值之后您保留的数据。
          【解决方案6】:

          假设此查询选择了您要保留的行:

          SELECT timestampcol FROM table ORDER BY timestampcol DESC LIMIT 49,1;
          

          然后你可以像这样使用子查询:

          DELETE FROM table WHERE timestampcol < ( SELECT timestampcol FROM table ORDER BY timestampcol DSEC LIMIT 49,1 )
          

          当然,在做任何具有潜在破坏性的事情之前,请确保您有备份。请注意,与使用IN 的其他方法相比,此方法将避免对要删除的每一行进行 50 次整数比较,使其(可能)快 50 倍 - 假设我的 SQL 正确。

          【讨论】:

          【解决方案7】:

          也许不是最有效的,但这应该可行:

          DELETE FROM _table_ 
          WHERE _date_ NOT IN (SELECT _date_ FROM _table_ ORDER BY _date_ DESC LIMIT 50)
          

          【讨论】:

          • 似乎不起作用,MYSQL5 不支持子查询中的 LIMIT:#1235 - 此版本的 MySQL 尚不支持 'LIMIT & IN/ALL/ANY/SOME 子查询
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-09-24
          • 2020-12-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-30
          相关资源
          最近更新 更多