会议室:DAO查询可删除以多个列为条件的重复项

时间:2018-12-13 19:35:22

标签: android sqlite dao android-room

假设我们正在使用Room,并且有一个DAO可以实现我们与SQLite表的交互。有没有一种方法可以构造一个查询,该查询可以标识具有相同值(即被视为重复项)的一个或多个列并删除它们?

例如我们有这张桌子:

primKey | name | lastname | phone |
 1        foo      bar       222
 2        foo      bar       333  
 3        oof      rab       123 

在这种情况下,我们认为namelastname是确定行是否相同的标准。因此,如果namelastname是相同的,我们将只保留一行,因为存在重复项。这里的1、2行是重复的。

More or less this,但是我无法使用例如USING table,但出现错误。而且我也不确定如何使用多列作为条件。

2 个答案:

答案 0 :(得分:1)

尝试在Query界面中创建以下DAO

@Dao
public interface MyDaoTest {

    ...

    @Query("DELETE FROM test
            WHERE id NOT IN (SELECT MIN(id) FROM test GROUP BY name, lastName)")
    void deleteDuplicates();

    ...
}

该查询将删除namelastName重复的所有行。

例如,如果我们有下表,我们可以看到ID为126的行是重复的,与ID为{{ 1}}和3,而带有4的行没有重复。

original table with duplicates

此查询将按5name对行进行分组,仅保留ID最小的行。这样一来,我们确保每组重复的行中只有一行(具有最小ID的行)

lastName

result of select min

最后,如果我们删除该内部查询结果中未包含ID的所有行,则将删除重复项。

SELECT MIN(id)
FROM test
GROUP BY name, lastName;

result

答案 1 :(得分:0)

您可以使用复合主键

SomeClass('aaa')
SomeClass('bbb', some_b_specific_option='some other value')
SomeClass(option='ccc')

因此,无论何时插入新值,如果@Entity(primaryKeys = ["name", "lastname"]) data class User( // you can ignore your primaryKey field val name: String, val lastname: String, val phone: Long ) name相同,都可以覆盖或忽略。

lastname