首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在MySQL中选择除顶N之外的所有

在MySQL中选择除顶N之外的所有
EN

Stack Overflow用户
提问于 2012-02-02 16:56:10
回答 3查看 1.8K关注 0票数 3

我有一个不需要保存很长时间的数据表,所以每天晚上我都想删除除最后20行之外的所有行。

为此,我发现了以下查询:

代码语言:javascript
复制
DELETE FROM Table WHERE ID NOT IN (
    SELECT id FROM (
        SELECT TOP 10 ID FROM Table
    ) AS x
)

MySQL不支持TOP函数,因此我将其重写为使用限制:

代码语言:javascript
复制
DELETE FROM Table WHERE ID NOT IN (
    SELECT id FROM (
        SELECT ID FROM Table ORDER BY ID DESC LIMIT 10
    ) AS x
)

不幸的是,MySQL似乎不支持子查询中的限制函数。那我现在该怎么办?

如何选择ID最高的10行以外的所有行?

我可能只是删除所有的记录,是超过一天或什么,但它觉得我应该能够这样做。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-02-02 17:30:01

另一种方式是:

代码语言:javascript
复制
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 
票数 1
EN

Stack Overflow用户

发布于 2012-02-02 17:21:27

由于MySQL在从您要删除的同一表中读取数据时存在缺陷,所以最简单的选项通常是使用临时表。

代码语言:javascript
复制
INSERT INTO yourTempTable
SELECT id FROM yourTable
ORDER BY ID DESC LIMIT 10

DELETE yourTable WHERE id IN (SELECT id FROM yourTempTable)

或其中的许多变体(使用联接而不是IN等)。

主要考虑的不是如何编写第二个查询,而是关于竞争条件。

您的数据可以由临时表和delete之间的另一个进程更改。如果这是可能的,而且重要的话,您需要将其全部包装在一个事务中,并在yourTable上设置一个表锁。

票数 2
EN

Stack Overflow用户

发布于 2012-02-02 17:00:30

有几种方法可以这样做,我更喜欢这样做:-

代码语言:javascript
复制
 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 :截断不会重置自动增量字段

ps2 :这种方法假设在截断期间没有写,可以发出锁以保持数据完整性。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9116436

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档