Mysql 保留最新的7条记录并删除所有其他查询问题

Mysql 保留最新的7条记录并删除所有其他查询问题,mysql,sql,Mysql,Sql,我有一张mysql表 CREATE TABLE IF NOT EXISTS `mytable` ( `i_contact_id` int(16) NOT NULL AUTO_INCREMENT, `s_contact_name` char(48) NOT NULL, `ts_contact_scraped` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Date Time when contact is last scra

我有一张mysql表

CREATE TABLE IF NOT EXISTS `mytable` (
  `i_contact_id` int(16) NOT NULL AUTO_INCREMENT,
  `s_contact_name` char(48) NOT NULL,
  `ts_contact_scraped` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Date Time when contact is last scraped.',
  PRIMARY KEY (`i_contact_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

INSERT INTO `mytable` (`i_contact_id`, `s_contact_name`, `ts_contact_scraped`) VALUES
(1, 'aaaa', '2018-07-27 02:30:30'),
(2, 'bbbb', '2017-03-28 04:13:08'),
(3, 'cccc', '2017-03-12 03:52:57'),
(4, 'dddd', '2017-04-18 07:13:34'),
(5, 'eeee', '2018-05-29 15:22:23'),
(6, 'ffff', '2018-02-23 13:27:24'),
(7, 'gggg', '2016-10-17 22:50:24'),
(8, 'hhhh', '2018-07-20 14:02:14'),
(9, 'iiii', '2020-03-24 10:56:02');
我想根据ts_contact_scraped字段保留7个最新的行并删除所有最旧的行,但它不能正常工作

这是我的删除查询

DELETE FROM `mytable`
  WHERE i_contact_id <= (
    SELECT i_contact_id
    FROM (
      SELECT i_contact_id
      FROM `mytable`
      ORDER BY ts_contact_scraped DESC
      LIMIT 1 OFFSET 7
    ) foo
  )
我的原始表有超过1100000行,我想使用PHP定期运行上述查询以清除最旧的行,还涉及一些其他逻辑,因此我想根据ts_contact_scraped字段删除最旧的行

当我在原始表上运行此查询时,它会删除超出预期的行

这是小提琴

您可以使用连接:

您可以使用“加入”:


在delete语句中,您依赖于较高的ts\U contact\U scraped,这也意味着较高的i\U contact\U id。至少在您的示例中没有给出这一点

因此,请坚持使用T_contact_scraped:

这是你的小提琴:


但是,如果有重复的Tsu联系人,事情会变得更复杂。

在您的delete语句中,您依赖的是较高的Tsu联系人,这也意味着较高的i\u联系人id。至少在您的示例中没有给出这一点

因此,请坚持使用T_contact_scraped:

这是你的小提琴:

但是,如果可以刮取重复的触点,事情会变得更复杂。

删除t1* 从'mytable`t1 左连接选择联系人id 从“我的桌子”` 订单由ts\U联系人\U刮削描述 t1.i_触点id上的限制7 t2=t2.i_触点id 其中t2.i_contact_id为空; 或

删除t1* 从“mytable”t1中,选择T_contact_scraped 从“我的桌子”` 订单由ts\U联系人\U刮削描述 限制1偏移量7 t2 其中t1.ts\u contact\u删除了t1* 从'mytable`t1 左连接选择联系人id 从“我的桌子”` 订单由ts\U联系人\U刮削描述 t1.i_触点id上的限制7 t2=t2.i_触点id 其中t2.i_contact_id为空; 或

删除t1* 从“mytable”t1中,选择T_contact_scraped 从“我的桌子”` 订单由ts\U联系人\U刮削描述 限制1偏移量7 t2
t1.ts\u contact\u scraped的位置比我的查询效率高吗?@Syed。1您必须测试它是否更有效。2它不起作用是一个无用的评论。为什么不行?比我的查询效率高吗?@Syed。1您必须测试它是否更有效。2它不起作用是一个无用的评论。为什么不起作用?创建一个新表可能会更有效,只保留要保留的行。我不想每次都创建新表。你能帮我找到一个好的工作解决方案吗?@Syed:草莓的意思是:创建一个包含七行的新表,删除原始表,将新表重命名为原始表的名称。如果您的表中包含的行数与您建议的一样多,则delete语句删除除七行以外的所有行可能会非常慢。@ThorstenKettner在我的原始表中大约有1100K行,当我添加25行时,可能比删除25行更有效。创建新表可能更有效,只保留要保留的行PI不想每次都创建新表。你能帮我找到一个好的工作解决方案吗?@Syed:草莓的意思是:创建一个包含七行的新表,删除原始表,将新表重命名为原始表的名称。如果您的表包含的行数与您建议的一样多,则delete语句删除除七行以外的所有行可能会非常慢。@ThorstenKettner在我的原始表中大约有1100K行,当我添加25行时,我必须删除25行。
DELETE t
    FROM `mytable` t JOIN 
         (SELECT i_contact_id
          FROM `mytable`
          ORDER BY ts_contact_scraped DESC
          LIMIT 1 OFFSET 7
         ) tt
         ON tt.i_contact_id = t.i_contact_id
DELETE FROM `mytable`
  WHERE ts_contact_scraped <= (
    SELECT ts_contact_scraped
    FROM (
      SELECT ts_contact_scraped
      FROM `mytable`
      ORDER BY ts_contact_scraped DESC
      LIMIT 1 OFFSET 7
    ) foo
  );