2

可能重复:
删除重复的行

这是我的表结构:

"作者" (varchar) | “点”(整数) | “主体)

作者总是一样的,身体也是。同一个作者条目会在整个数据库中以不同的主体出现多次,所以我无法根据作者删除。但是,点列并不总是相同的。我想要保留具有最大点值的行。

我正在使用 SQLite3 和 Python。

谢谢

编辑:

我已经尝试过了,但它只是删除了所有行。

for row in cur.fetchall():
        rows = cur.execute('SELECT * FROM Posts WHERE Author=? AND Body=? AND Nested=? AND Found=?', (row['Author'], row['Body'], row['Nested'], row['Found'],))
        for row2 in rows:
            delrow = row
            if (row['Upvotes'] <  row2['Upvotes'] or row['Downvotes'] < row2['Downvotes']):
                delrow = row2
            cur.execute("DELETE FROM Posts WHERE Author=? AND Body=? AND Upvotes=? AND Downvotes=? AND Nested=? AND Found=?", (delrow['Author'], delrow['Body'], delrow['Upvotes'], delrow['Downvotes'], delrow['Nested'], delrow['Found'],))
            dn += 1
            print "Deleted row ", dn

我也试过这个,但没有奏效。

cur.execute("DELETE FROM Posts WHERE Upvotes NOT IN (SELECT MAX(Upvotes) FROM Posts GROUP BY Body);")

我也提交了所有的更改,所以不是这样。SQLite3 模块安装正确,我可以在数据库上写。

4

3 回答 3

2

不幸的是,在 SQLite3 中,您没有像partition over row这样的好功能,因此无法在一个查询中执行此操作,因此您必须以程序方式或迭代方式执行此操作。

出于性能原因,我建议您提取删除潜力的完整列表,然后将它们整体删除,例如。

# in your sql query
SELECT ROWID, AUTHOR, BODY
FROM   TABLE_NAME
ORDER BY AUTHOR, BODY, POINTS DESC

然后在您的 Python 应用程序中,遍历您的结果集,并为 Author/Body 组合存储所有非第一个 ROWID(想想 CTRL-BREAK 样式编程),一旦您完成构建集删除行 ID。

于 2012-06-21T20:12:27.473 回答
1

由于您要删除除最高分值之外的所有值,因此以下操作就可以了:

delete from test
  where exists (select * from test t2
                where test.author = t2.author
                and test.body = t2.body
                and test.points < t2.points);

它是对自身的基本连接,然后删除所有具有相同作者和正文但具有较低点值的值。

SqlFiddle在这里: http ://sqlfiddle.com/#!7/64d62/3

注意:一个警告是,如果多个作者/正文对具有相同的最大点值,那么所有这些值都将被保留。

于 2012-06-21T20:31:26.460 回答
0

我还没有测试过,但这可能有效:

DELETE FROM TableName
    WHERE author, body, points NOT IN (SELECT author, body, MAX(points) as points
        FROM TableName 
    GROUP BY author, body)

首先将其作为 SELECT 查询运行,以查看它是否会保留您想要的内容。

于 2012-06-21T20:17:25.880 回答