Сохраните последние 7 записей и удалите все остальные вопросы запроса - PullRequest
1 голос
/ 24 марта 2020

У меня есть 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');

Я хочу сохранить 7 последних строк и удалить все самые старые строки на основе поля ts_contact_scraped, но он не работает должным образом.

Вот мой запрос на удаление

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 для очистки самых старых строк, есть некоторые другие логики c, задействованные так Я хочу удалить самые старые строки на основе поля ts_contact_scraped.

Когда я запускаю этот запрос в моей исходной таблице, он удаляет больше, чем ожидалось, строк.

Вот скрипка http://sqlfiddle.com/#! 9 / 9414e2 / 1/0

Ответы [ 3 ]

0 голосов
/ 24 марта 2020

В своем утверждении об удалении вы полагаетесь на более высокое ts_contact_scraped, что также означает более высокое i_contact_id. По крайней мере, в вашем примере это не дано.

Поэтому придерживайтесь ts_contact_scraped вместо:

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
  );

Вот ваша измененная скрипка: http://sqlfiddle.com/#! 9 / 610cb4 / 1

(Однако, если может быть дубликат ts_contact_scraped, все будет сложнее.)

0 голосов
/ 24 марта 2020
DELETE t1.*
FROM `mytable` t1
LEFT JOIN ( SELECT i_contact_id
            FROM `mytable`
            ORDER BY ts_contact_scraped DESC
            LIMIT 7 ) t2 ON t1.i_contact_id = t2.i_contact_id
WHERE t2.i_contact_id IS NULL;

скрипка

или

DELETE t1.*
FROM `mytable` t1, ( SELECT ts_contact_scraped
                     FROM `mytable`
                     ORDER BY ts_contact_scraped DESC
                     LIMIT 1 OFFSET 7 ) t2
WHERE t1.ts_contact_scraped <= t2.ts_contact_scraped;

скрипка

0 голосов
/ 24 марта 2020

Вы можете использовать JOIN:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...