删除除最近的50行外的所有行

时间:2020-03-06 14:51:03  来源:igfitidea点击:

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

解决方案

块引用

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

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

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

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

假设此查询选择我们要保留的行:

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次整数比较,假设我正确地使用了SQL,那么它(可能)会快50倍。

好吧,看起来好像我们无法在一个查询中做到这一点,如果我错了,有人会纠正我。我曾经做过这种事情的唯一方法是首先弄清楚表中的行数。例如:

select count(*) from table;

然后使用结果做

delete from table order by timestamp limit result - 50;

我们必须采用这种方式,原因有两个:

  • MySQL 5不支持删除子查询中的限制
  • MySQL 5不允许我们从要删除的同一表中选择子查询。

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

由于MySQL5尚不支持LIMIT的子查询,我最终使用了两个查询

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