Удалить все, кроме последних 500 строк из базы данных sqlite

У меня неплохой SQL, но SQLite на iOS меня постоянно подводит.

У меня есть таблица, в которой я хочу ограничить количество строк примерно до 500, поэтому, когда она достигнет точки срабатывания, скажем, 550, она удалит самые ранние 50 строк.

Он движется, поэтому со временем идентификатор не всегда будет начинаться с единицы, и пользователь может удалять строки, поэтому идентификатор не является последовательным.

У меня есть поле juliandate (double), но я не уверен, что оно пригодится

DELETE FROM contents WHERE id > '0' ORDER BY id DESC LIMIT 0, 50
DELETE FROM contents ORDER BY id DESC LIMIT 0, 50

Документация говорит, что это нормально, но это не работает. Любые идеи?


person JulianB    schedule 14.03.2012    source источник
comment
Как это не удается? Сообщение об ошибке или просто ничего не удаляет или удаляет не то? Почему бы вам не использовать поле даты, чтобы удалить самые старые 50?   -  person Nick Bull    schedule 14.03.2012
comment
@NickBull, 1. Sqlite3 не так много говорит об ошибках: Error: near "LIMIT": syntax error. 2. может отсутствовать поле даты.   -  person Misha Akovantsev    schedule 14.03.2012
comment
@MishaAkovantsev 1. Этого сообщения об ошибке достаточно, чтобы увидеть синтаксическую ошибку, а не ошибку, заключающуюся в удалении неправильных записей. 2. ОП говорит, что у меня есть поле juliandate   -  person Nick Bull    schedule 15.03.2012
comment
@NickBull 1. правда, но мне это не помогло. 2. правда, совсем проглядел.   -  person Misha Akovantsev    schedule 15.03.2012


Ответы (4)


что-то в этом духе, может быть?

delete from contents where juliandate <= (
    select max(juliandate) from (
        select juliandate from contents order by juliandate limit 0, 50));

Вы можете использовать id вместо juliandate или любого другого поля, значение которого увеличивается с каждой вставкой.

person user1096188    schedule 14.03.2012
comment
StackOverflow - делаем интернет круче, чем могут одни только порно и котята - спасибо пользователю 1096188! - person JulianB; 14.03.2012
comment
Это не сработало для меня, в то время как ответ thecr0w сработал. Проверьте это, если это не работает для вас. - person Vern Jensen; 14.01.2014

Хранить последние 500 записей:

delete
from table_name
where _id not
  in (select _id
    from table_name
    order by
      _id desc
    limit 500)
person thecr0w    schedule 28.06.2013
comment
поздравляю, но это просто зависит. - person thecr0w; 15.01.2014

DELETE FROM contents WHERE id IN (SELECT id FROM t ORDER BY id ASC LIMIT 50)

DESC означает 5,4,3,2,1, используйте его для удаления the freshest записей.
ASC означает 1,2,3,4,5, используйте его для удаления the earliest записей.

Вот пример:

$ sqlite3 /tmp/del_rows.sqlite3
CREATE TABLE t (id INTEGER PRIMARY KEY, value TEXT);
INSERT INTO t (value) VALUES ('a');
INSERT INTO t (value) VALUES ('b');
INSERT INTO t (value) VALUES ('c');
INSERT INTO t (value) VALUES ('d');
INSERT INTO t (value) VALUES ('e');
INSERT INTO t (value) VALUES ('f');
SELECT * FROM t;
-- 1|a
-- 2|b
-- 3|c
-- 4|d
-- 5|e
-- 6|f

-- Deleting 2 top rows:
DELETE FROM t WHERE id IN (SELECT id FROM t ORDER BY id ASC LIMIT 2);
SELECT * FROM t;
-- 3|c
-- 4|d
-- 5|e
-- 6|f

-- And again:
DELETE FROM t WHERE id IN (SELECT id FROM t ORDER BY id ASC LIMIT 2);
SELECT * FROM t;
-- 5|e
-- 6|f
person Misha Akovantsev    schedule 14.03.2012
comment
Это будет удалять n строк каждый раз, но не удалять все, кроме последних 500 строк. Я думаю, это означает, что нужно сохранить последние 500 записей. - person thecr0w; 28.06.2013

Попробуйте это. Это должно быть то, что вы ищете:

DELETE FROM contents WHERE id IN 
    (SELECT id FROM contents ORDER BY id LIMIT 50 ASC);

Читайте также, аналогичный вопрос: Сохранить только N последним записи в базе данных SQLite, отсортированные по дате

person Evgen Bodunov    schedule 14.03.2012
comment
Увы, нет, не уверен, почему бы и нет, но SQLite кажется лишней причудливостью. - person JulianB; 14.03.2012
comment
Вы имеете в виду сохранить последние 500 записей? - person thecr0w; 28.06.2013