首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >删除数据库中的所有项目,但上次日期除外

删除数据库中的所有项目,但上次日期除外
EN

Stack Overflow用户
提问于 2019-12-28 13:55:02
回答 3查看 733关注 0票数 2

我有一个MySQL表,它看起来(非常简化)如下:

代码语言:javascript
复制
CREATE TABLE `logging` (
  `id` bigint(20) NOT NULL,
  `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `level` smallint(3) NOT NULL,
  `message` longtext CHARACTER SET utf8 COLLATE utf8_general_mysql500_ci NOT NULL
);

我想删除一个特定level的所有行,除了最后一个行(time是最近的)。

是否有一种方法可以选择将level设置为特定值的所有行,然后删除单个查询中的最新行之外的所有行?我该如何开始解决这个问题呢?

(正如我所说,这是一个非常简化的表格,所以请不要试图讨论这个表的可能设计问题。我移走了一些柱子。它是按照PSR-3测井标准设计的,我不认为有一种简单的方法可以改变这种情况。我想解决的是如何从一个表中选择,然后删除同一表中的所有行(除了一些行)。我只有MySQL的中级知识。)

(谢谢你把我推向正确的方向:)

编辑:

数据库版本为/usr/sbin/mysqld Ver 8.0.18-0ubuntu0.19.10.1,用于Linux on x86_64 ((Ubuntu))

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-12-28 14:06:10

您可以使用ROW_NUMBER()解析函数(如使用DB版本8+ ):

代码语言:javascript
复制
DELETE lg FROM `logging` AS lg
 WHERE lg.`id` IN
      ( SELECT t.`id` 
          FROM
         (
          SELECT t.*,
                 ROW_NUMBER() OVER (ORDER BY `time` DESC) as rn
            FROM `logging` t
       --  WHERE `level` = @lvl -- optionally add this line to restrict for a spesific value of `level`
         ) t
         WHERE t.rn > 1
       )

删除除最后插入的行之外的所有行(考虑到id是您的主键列)。

票数 2
EN

Stack Overflow用户

发布于 2019-12-28 14:52:32

你可以这样做:

代码语言:javascript
复制
SELECT COUNT(time) FROM logging WHERE level=some_level INTO @TIME_COUNT;
SET @TIME_COUNT = @TIME_COUNT-1;
PREPARE STMT FROM 'DELETE FROM logging WHERE level=some_level ORDER BY time ASC LIMIT ?;';
EXECUTE STMT USING @TIME_COUNT;
票数 0
EN

Stack Overflow用户

发布于 2019-12-28 15:34:09

如果您有一个AUTO_INCREMENT id列-我将使用它来确定最近的条目。有一个方法是这样做的:

代码语言:javascript
复制
delete l
from (
  select l1.level, max(id) as id
  from logging l1
  where l1.level = @level
) m
join logging l
  on  l.level = m.level
  and l.id    < m.id

(level)上的索引应该为您提供良好的性能,并将支持MAX()子查询和连接。

关于DB Fiddle的看法

如果确实需要使用time列,可以按以下方式修改查询:

代码语言:javascript
复制
delete l
from (
  select l1.level, l1.id
  from logging l1
  where l1.level = @level
  order by l1.time desc, l1.id desc
  limit 1
) m
join logging l
  on  l.level = m.level
  and l.id   <> m.id

关于DB Fiddle的看法

在这里,您可能希望在(level, time)上有一个索引。

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

https://stackoverflow.com/questions/59511518

复制
相关文章

相似问题

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