Удалить все, кроме 50 новых строк - PullRequest
3 голосов
/ 28 сентября 2008

У меня есть таблица SQL с новостями и метками времени Unix. Я хотел бы сохранить только 50 новейших историй. Как бы я написал оператор SQL для удаления любого количества старых историй?

Ответы [ 6 ]

8 голосов
/ 28 сентября 2008

Blockquote

delete from table where id not in (
    select id from table 
    order by id desc 
    limit 50
)

Вы выбираете идентификаторы данных, которые не хотите удалять, и удаляете все НЕ В этих значениях ...

6 голосов
/ 29 сентября 2008

В итоге я использовал два запроса, поскольку MySQL5 еще не поддерживает LIMIT в подзапросах

SELECT unixTime FROM entries ORDER BY unixTime DESC LIMIT 49, 1;
DELETE FROM entries WHERE unixTime < $sqlResult;
3 голосов
/ 29 сентября 2008

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

select count(*) from table;

затем, используя результат, сделайте

delete from table order by timestamp limit result - 50;

Вы должны сделать это таким образом по двум причинам -

  1. MySQL 5 не поддерживает ограничение в подзапросах для удаления
  2. MySQL 5 не позволяет выбирать в подзапросе из той же таблицы, из которой вы удаляете.
2 голосов
/ 29 сентября 2008

Если у вас много строк, может быть лучше поместить 50 строк во временную таблицу затем используйте TRUNCATE TABLE , чтобы очистить таблицу. Затем поместите 50 строк обратно.

0 голосов
/ 28 сентября 2008

Предполагая, что этот запрос выбирает строки, которые вы хотите сохранить:

SELECT timestampcol FROM table ORDER BY timestampcol DESC LIMIT 49,1;

Тогда вы можете использовать подзапрос, например, так:

DELETE FROM table WHERE timestampcol < ( SELECT timestampcol FROM table ORDER BY timestampcol DSEC LIMIT 49,1 )

Конечно, убедитесь, что у вас есть резервная копия, прежде чем делать что-либо потенциально разрушительное. Обратите внимание, что по сравнению с другими упомянутыми подходами, использующими IN, этот способ позволит избежать 50 целочисленных сравнений для каждой удаляемой строки, что сделает его (потенциально) в 50 раз быстрее - при условии, что я правильно понял SQL.

0 голосов
/ 28 сентября 2008

Возможно, не самый эффективный, но это должно работать:

DELETE FROM _table_ 
WHERE _date_ NOT IN (SELECT _date_ FROM _table_ ORDER BY _date_ DESC LIMIT 50)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...