【发布时间】:2020-06-07 07:37:52
【问题描述】:
这是一个简单的问题。
背景
我应该在某个表中最多有 400 行,基于时间戳字段,所以旧的将被自动删除。在这里,假设它是 3。
表格有各种字段,但时间戳在这里很重要。
问题
即使我成功了(看起来here),由于某种原因,它让我最多获得了一个额外的项目,所以我只是相应地调整了它。这意味着我得到了 4 个项目,而不是 3 个。
private const val MAX_ITEMS = 3
private val TIMESTAMP_FIELD = "timestamp"
private val DELETE_FROM_CALL_LOG_TILL_TRIGGER =
String.format(
"CREATE TRIGGER %1\$s INSERT ON %2\$s
WHEN (select count(*) from %2\$s)>%3\$s
BEGIN
DELETE FROM %2\$s WHERE %2\$s._id IN " +
"(SELECT %2\$s._id FROM %2\$s ORDER BY %2\$s.$TIMESTAMP_FIELD DESC LIMIT %3\$d, -1);
END;"
, "delete_till_reached_max", TABLE_NAME, MAX_ITEMS - 1)
我尝试过的
我试过了:
- 将条件更改为只是插入(意味着没有
WHEN部分) - 将
LIMIT %3\$d, -1更改为LIMIT -1 OFFSET %3\$d。还尝试了与“-1”不同的数字(尝试了 0,因为我认为它是多余的)。
问题
- 为什么我必须使用
MAX_ITEMS - 1而不仅仅是MAX_ITEMS?为什么它给我留下 4 件而不是 3 件? - 我有
WHEN有关系吗?好点了吗?
【问题讨论】:
-
如果有 400 个项目不是绝对关键,您也许可以从 rowid
-
@CaiusJard 为什么要使用 ID?它总是在增加......
-
呃,是的.. 我以为这就是您要问的 - 维护 400 个项目的更好/更简单的方法是使用递增数字并删除所有 LTE 当前数字减去 400。这意味着删除可以用数学来完成,你很容易知道(刚刚插入的记录的 id),而不必按日期 desc 对 N 个项目进行排序,取第 400 个项目的日期并删除所有 LTE 它
-
如果ID一直在增加,SQLite只支持
FOR EACH ROW触发器,那么我们说的是删除一行。这是插入前触发器中的delete from mytable where id = (select min(id) from mytable group by null having count(*) = 400)或后行触发器中的> 400。 -
各位,我应该从事的领域不是 ID。它是时间戳(长类型)。我需要从该字段中删除最旧的,即具有最低值的那些。如果我使用 ID,那么只有在我总是添加具有较新 ID 的新项目并按此类排序时才有意义。
标签: sql sqlite android-sqlite