删除sqlite中的重复行?

时间:2014-01-07 04:25:26

标签: python sqlite duplicates duplicate-removal

如何输入相同的条目? 我的表播放器有两个方面(名称,wowp_id)复制。如何合并?

我一直在寻找相关问题。下面的代码建立在我找到的答案之上。流程运行良好,但重复仍然存在。我希望没有重复的名称。如果多个名称存在不同的 wowp_id ,我希望删除 wowp_id 并仅保留一个名称条目。

def sql_removeduplicates():
    con = sqlite3.connect('WOWT.sql')
    with con:    
        cur = con.cursor()    
        cur.execute("SELECT name, COUNT(*) FROM players GROUP BY name, team, wowp_id HAVING COUNT(*) > 1")
        rows = cur.fetchall()
        con.commit()
        for row in rows:
            print row

我在玩家中的行:

  (id, wowp_id, name, team)
(108, 501078041, u'prazluges', None)
(109, 507894244, u'Aidis', None)
(110, 500742127, u'Aidis', None)
(111, u'Aidis', u'Aidis', None)
(112, u'Aidis', u'Aidis', None)
(113, 500864543, u'prazluges', None)
(114, u'Aidis', u'Aidis', None)
(115, u'Aidis', u'Aidis', None)
(116, u'Aidis', u'Aidis', None)
(117, 501078041, u'satih', None)
(118, u'Aidis', u'Aidis', None)

4 个答案:

答案 0 :(得分:2)

您可以在列上定义唯一索引,或使用索引列在表上定义唯一约束。

CREATE UNIQUE INDEX IF NOT EXISTS ...

CREATE TABLE IF NOT EXISTS ... (..., UNIQUE(col1, col2, col3), ...)

这些有助于防止重复出现之前。链接到SQLite文档。

答案 1 :(得分:2)

你可以做到

DELETE FROM players
 WHERE id NOT IN
(
  SELECT MIN(id) id
    FROM players
   GROUP BY wowp_id, name
);

注意:,然后继续DELETE,确保您拥有可靠的数据备份。

从表格中删除重复项后,请务必创建UNIQUE约束

CREATE UNIQUE INDEX idx_wowp_id_name ON players(wowp_id, name);

扣除后的结果:

|  id |   wowp_id |      name | team |
|-----|-----------|-----------|------|
| 108 | 501078041 | prazluges | None |
| 109 | 507894244 |     Aidis | None |
| 110 | 500742127 |     Aidis | None |
| 111 |     Aidis |     Aidis | None |
| 113 | 500864543 | prazluges | None |
| 117 | 501078041 |     satih | None |

这是 SQLFiddle 演示

答案 2 :(得分:1)

将结果导入自定义类的set,并定义包含方法以保留您想要的内容。示例如下:

class players:
   def __contains__(self, item):
        return self.playersObj.name != item.name
   # Your other methods go here

然后将您的行导入到玩家的实例中并将其写回。

答案 3 :(得分:0)

听起来你正试图删除同一个NAME的重复WOWP_ID。我假设你为每个NAME保留了最大的WOWP_ID。如果您有一个可靠的唯一键,例如表中的主键,答案很简单。如果你没有这样的钥匙,你可以尝试这样的事情:

import unittest
import sqlite3

class DaoTest(unittest.TestCase):                
    def testDeleteDuplicates(self):
        with sqlite3.connect("WOWT.sql") as conn:
            rowsToDelete = conn.execute('''
                SELECT PLAYERS.NAME, PLAYERS.TEAM, PLAYERS.WOWP_ID FROM PLAYERS INNER JOIN 
                (
                    SELECT PLAYERS.NAME, MAX(WOWP_ID) AS MAX_ID FROM PLAYERS INNER JOIN
                    (
                        SELECT NAME, COUNT(DISTINCT WOWP_ID) AS DUP FROM PLAYERS
                        GROUP BY NAME
                        HAVING DUP > 1
                    ) DUPTABLE
                    ON PLAYERS.NAME = DUPTABLE.NAME
                    GROUP BY PLAYERS.NAME
                ) RowsToKeep
                ON PLAYERS.NAME = RowsToKeep.NAME AND PLAYERS.WOWP_ID <> MAX_ID
            ''')
            conn.executemany("DELETE FROM PLAYERS WHERE NAME = ? AND TEAM = ? AND WOWP_ID = ?", rowsToDelete)