我有一个数据表,我不需要保留很长时间,因此每天晚上我都要删除除最后20行之外的所有行。
为此,我找到了以下查询:
DELETE FROM Table WHERE ID NOT IN (
SELECT id FROM (
SELECT TOP 10 ID FROM Table
) AS x
)
MySQL不支持TOP功能,所以我改写它来改为使用LIMIT:
DELETE FROM Table WHERE ID NOT IN (
SELECT id FROM (
SELECT ID FROM Table ORDER BY ID DESC LIMIT 10
) AS x
)
不幸的是,MySQL似乎不支持子查询中的LIMIT函数。那我现在该怎么办?
如何选择ID最高的10行以外的所有内容?
我可能只是删除所有超过一天或某事的记录,但感觉我应该能够这样做。
答案 0 :(得分:2)
由于MySQL在删除时从同一个表读取时没有用,因此最简单的选择通常是使用临时表。
INSERT INTO yourTempTable
SELECT id FROM yourTable
ORDER BY ID DESC LIMIT 10
DELETE yourTable WHERE id IN (SELECT id FROM yourTempTable)
或其中的许多变体(使用连接而不是IN等)。
主要考虑因素不是关于如何编写第二个查询,而是关于竞争条件。
您的数据可能会被临时表和删除之间的其他进程更改。如果这是可能的并且很重要,您需要将它全部包装在事务中并在yourTable
上打一个表锁。
答案 1 :(得分:1)
另一种方式:
DELETE t
FROM
TableX AS t
CROSS JOIN
( SELECT Id
FROM TableX
ORDER BY Id DESC
LIMIT 1 OFFSET 9
) AS tenth
WHERE t.Id < tenth.id
答案 2 :(得分:0)
有几种方法可以做到这一点,我更喜欢这样: -
create table tmp_table select * from your_table order by id desc limit 20;
truncate table your_table;
insert into your_table select * from tmp_table;
drop table tmp_table;
乍一看似乎非常冗长,PS:truncate不会重置自动增量字段
ps2:这种方法假设在截断期间没有写入,可以发出锁定以保持数据完整性