Как можно удалить старые записи, оставив, как минимум, одну последнюю для каждого датчика?

В таблицу channel_snapshots пишутся отчёты состояния с разных датчиков (snapshot_time, FK channel_id). Чтобы держать размер таблицы контролируемым, старые записи свыше 12 часов нужно удалять, но так, чтобы не был удалён последний старый отчёт датчика, который по каким-то причинам не отправил отчёт. То есть нужно оставить 1 последний отчёт каждого датчика, от которого не был отправлен отчёт более 12 часов назад.

На данный момент же удаляются банально все старые записи свыше 12 часов и даже те, которые нужно оставить поштучно.
Вопрос: можно ли выполнить эту задачу одним запросом, учитывая данную логику? Если да, то как?
  • Вопрос задан
  • 484 просмотра
Решения вопроса 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
DELETE `t1`
  FROM `channel_snapshots` AS `t1`
  LEFT JOIN (
    SELECT MAX(`snapshot_time`) AS `time`, `channel_id`
      FROM `channel_snapshots`
      GROUP BY `channel_id`
  ) AS `t2` ON `t2`.`time` = `t1`.`snapshot_time` AND `t2`.`channel_id` = `t1`.`channel_id`
  WHERE `t1`.`snapshot_time` < NOW() - INTERVAL 12 HOUR 
    AND `t2`.`channel_id` IS NULL
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@Dronablo
Oracle performance geek
В диалекте Oracle SQL:
DELETE
FROM
  ALL_SNAPSHOTS
WHERE
  SNAPSHOT_TIME                       <=SYSDATE-12/24
  AND (SNAPSHOT_TIME, ID_CHANNEL) NOT IN
  (
    SELECT MAX(SNAPSHOT_TIME), ID_CHANNEL FROM ALL_SNAPSHOTS GROUP BY ID_CHANNEL
  );
Ответ написан
NeiroNx
@NeiroNx
Программист
вначале надо получить ид верхних записей. группируя по типу датчика, потом удалить все кроме этих
DELETE `tab` WHERE `id` NOT IN (SELECT max(id) FROM `tab` GROUP BY `channel`)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы