如何输入相同的条目? 我的表播放器有两个方面(名称,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)
答案 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)