在MySQL中删除“旧”行的正确方法

在MySQL中删除“旧”行的正确方法,mysql,sql,Mysql,Sql,我的桌子有一个时间域 我只想保留最新的5行 我可以不使用SELECT删除旧行吗 我认为逻辑应该是这样的: DELETE FROM tbl WHERE row_num > 5 ORDER BY TIME 如何在MySQL whitout中使用SELECT获取时间值列表来实现这一点 这将删除6、7、8、9、10、…、200005中的记录 因为此处的限制范围从6到9999条记录开始,意味着200005条记录。如果要排除前5行,请使用以下命令: DELETE FROM table WHERE

我的桌子有一个时间域

我只想保留最新的5行

我可以不使用SELECT删除旧行吗

我认为逻辑应该是这样的:

DELETE FROM tbl WHERE row_num > 5 ORDER BY TIME
如何在MySQL whitout中使用SELECT获取时间值列表来实现这一点

这将删除6、7、8、9、10、…、200005中的记录


因为此处的限制范围从6到9999条记录开始,意味着200005条记录。如果要排除前5行,请使用以下命令:

DELETE FROM table WHERE  primary_key IN 
(SELECT primary_key FROM table LIMIT 1 OFFSET 5,1000000)
100000可以是非常大的no

,如果没有适当的orderby子句,SQL结果集必须被视为无序的

您必须提供一个列来显式存储行序列号。这可能是一个时间戳,也可能是表的自动增量列

请记住,您也可以同时访问您的表。如果在您删除时其他人正在插入,那么预期的行为应该是什么?据我所知,这可能会导致这样的情况:您只保留最新的5行+在另一个事务中插入的行

如果您的表中有用于此目的的时间列和主键或其他唯一的非空列,您可以编写:

DELETE tbl FROM tbl LEFT JOIN (SELECT * FROM tbl ORDER BY tm DESC LIMIT 5) AS k
    ON (tbl.pk) = (k.pk)
    WHERE k.`time` IS NULL;
DELETE tbl FROM tbl LEFT JOIN (SELECT * FROM tbl ORDER BY tm DESC LIMIT 5) AS k
    ON (tbl.a,tbl.b) = (k.a,k.b)
    WHERE k.tm IS NULL;
如果您有复合主键a,b,则可以编写:

DELETE tbl FROM tbl LEFT JOIN (SELECT * FROM tbl ORDER BY tm DESC LIMIT 5) AS k
    ON (tbl.pk) = (k.pk)
    WHERE k.`time` IS NULL;
DELETE tbl FROM tbl LEFT JOIN (SELECT * FROM tbl ORDER BY tm DESC LIMIT 5) AS k
    ON (tbl.a,tbl.b) = (k.a,k.b)
    WHERE k.tm IS NULL;

也许这是另一种选择:

DELETE FROM tbl 
WHERE  primary_key NOT IN (SELECT primary_key 
                           FROM tbl 
                           ORDER BY time
                           DESC LIMIT 5)

你的问题不清楚。首先使其正确。在此查询中添加限制599999。并且还具有按时间描述的顺序,而不是ASC默认值。因为它写的都是大写字母,所以单词TIME是指表中的一个实际列,还是某种占位符?你能有一些具有相同时间值的列吗?还是唯一的?OP最初说我有一些带有某种时间字段的行列表。我把它编辑到我的表有一个时间域。他已经有一个时间域了。我同意存在潜在的竞争条件。@Paul我不太确定,因为它将所有大写字母拼写为保留关键字…假设时间或时间是每行的时间戳,我更关心的是MySQL DELETE的文档在限制后有一个空数字,例如限制3,而不是一个窗口,例如限制10,15。因此,限制510000000000可能无效。他还特别说他想避免SELECT子句,但可能需要一个。似乎很难同时避免子SELECT和相当不雅的限制5,biiiig__________________________________________?