Sqlite 删除逻辑上的重复记录

有个会话的表没有加唯一约束,导致在某些情况下会出现数据重复的情况,直接在升级脚本加约束会有可能失败, 所以需要在升级脚本删掉逻辑上面重复的记录,同时要保留第一条记录,然后再增加唯一约束。

先看表结构,一些无关的字段已经删除。

1
2
3
4
5
6
7
CREATE TABLE "YYSession" (
  [sessionId] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
  [sessionTitle] CHAR,      // 会话标题
  [roleId] CHAR,            // 发送角色id
  [sessionType] INTEGER,    // 会话类型,如单聊,群聊
  [objectId] CHAR,          // 对方的id,如角色id,群id
);

从 google 搜索了一下,参考一些搜索结果,应该是这么写:

1
2
3
4
5
6
delete from YYSession where (roleId, objectId, sessionType) in
    (select roleId, objectId, sessionType from YYSession 
        group by roleId, objectId, sessionType having count(*) > 1)
and rowid not in 
    (select min(rowid) from YYSession 
        group by roleId, objectId, sessionType having count(*) > 1)

实际测试发现 Sqlite 不支持delete时候多个in查询,后面改成了这样:

1
2
3
4
5
6
delete from YYSession where (roleId || "-" || objectId || "-" || sessionType) in      
    (select roleId || "-" || objectId || "-" || sessionType from YYSession 
        group by roleId, objectId, sessionType having count(*) > 1)
and rowid not in 
    (select min(rowid) from YYSession 
        group by roleId, objectId, sessionType having count(*) > 1)

测试成功。