Android 房间数据库 - 删除超过行限制的行?

Android Room database - Delete rows after row limit?

我正在尝试删除 1000 行限制后的所有非活动行,我试过这个:

@Query("DELETE FROM limit_orders where time_created NOT IN (SELECT is_active FROM limit_orders WHERE is_active = 0 ORDER BY time_created DESC LIMIT 1000)")
void cleanInactiveLimitHistory();

但它正在删除 table 中的所有内容。

编辑:

我试过了,但它会删除所有不活跃的订单:

@Query("DELETE FROM limit_orders WHERE is_active = 0 NOT IN (SELECT is_active FROM limit_orders WHERE is_active = 0 ORDER BY time_created DESC LIMIT 1000)")

我想保留前 1000 个非活动订单并删除剩余的旧非活动订单。我还想保留所有有效订单。

您的 SQL 陈述似乎不正确,请尝试以下内容

@Query("DELETE FROM limit_orders where time_created NOT IN (SELECT time_created FROM limit_orders WHERE is_active = 0 ORDER BY time_created DESC LIMIT 1000)")

请注意您的子查询返回了您期望的错误值

简而言之,您是在将橙子与苹果进行比较,因为 none 匹配全部被删除

子查询 SELECT is_active FROM limit_orders WHERE is_active = 0 ORDER BY time_created DESC LIMIT 1000 return 是 is_active 值的列表,当 is_active 为 0。因此,除非 is_active 包含与 time_created[= 中的一个或多个值匹配的值(日期) 69=] 列然后行将被删除。

您需要进行同类比较(橙子对橙子),因此您需要提取 time_created 列而不是 is_active 来自用于比较的子查询的列。

所以你可能应该使用 :-

@Query("DELETE FROM limit_orders where time_created NOT IN (SELECT time_created /*<<<<<<<<<<CHANGED COLUMN*/ FROM limit_orders WHERE is_active = 0 ORDER BY time_created DESC LIMIT 1000)")
  • 您可能不会包括评论 /*<<<<<<<<<<CHANGED COLUMN*/,这只是为了显示所做的更改。
  • 如果您在 time_created 列上没有索引(如果 time_created 是主键列)最好在该列上添加索引。

但是,我怀疑以上不会做你wish/expect。

子查询将 return 1000 行(或最多 1000 行),因此 DELETE 将删除所有其他行 (所以如果 table 有 10000 行,你会剩下 1000 行(假设唯一的 time_created 列,如下所述)).

相反,我怀疑您想删除 1000 行非活动(假设 0 - 非活动)行,因此您真的想删除已提取的 1000 行,所以您需要 IN 而不是 NOT IN。

注意,如果time_created列不是唯一的(如果它是房间中的PRIMARY KEY @PrimaryKey,则暗示UNQIUE) 然后可以删除其他行。如果行可以具有相同的 time_created,那么您可以改用 rowid 列。

  • rowid列是一直存在的列(WITHOUT ROWID table除外,which room doesn't account for via annotations)但被隐藏了。不过你可以随时参考它。它永远是独一无二的。

  • 所以使用 sure-fire 只删除你可能拥有的 1000 行:-

  • @Query("DELETE FROM limit_orders where rowid IN (SELECT rowid FROM limit_orders WHERE is_active = 0 ORDER BY time_created DESC LIMIT 1000)")

或者你想要

重新阅读您的问题听起来好像您可能想要保留 1000 个非活动行并删除其他非活动行。因此保留 100 个非活动行以及所有活动行。

如果是这种情况,那么最初的答案很接近,除了你还想(AND) 保留活动。

因此,您需要的是保留活动行的附加条件:-

@Query("DELETE FROM limit_orders WHERE time_created NOT IN (SELECT time_created /*<<<<<<<<<<CHANGED COLUMN*/ FROM limit_orders WHERE is_active = 0 ORDER BY time_created DESC LIMIT 1000) /*PRESERVE ACTIVEs >>>>>>>>>>*/ AND is_active <> 0")