如何删除PostgreSQL中sorting的固定行数?

我试图将一些旧的MySQL查询移植到PostgreSQL,但是我遇到了这个问题:

DELETE FROM logtable ORDER BY timestamp LIMIT 10; 

PostgreSQL不允许sorting或限制其删除语法,并且表没有主键,所以我不能使用子查询。 此外,我想保留查询删除给定数量或logging的行为,例如,如果表中包含30行,但它们都具有相同的时间戳,我仍然想要删除10,尽pipe它并不重要其中10。

所以; 在PostgreSQL中如何删除固定数量的行?

编辑:没有主键意味着没有log_id列或类似的。 啊,遗留系统的乐趣!

你可以尝试使用ctid

 DELETE FROM logtable WHERE ctid IN ( SELECT ctid FROM logtable ORDER BY timestamp LIMIT 10 ) 

ctid是:

行版本在其表中的物理位置。 请注意,尽pipe可以使用ctid非常快地定位行版本,但如果更新或移动了VACUUM FULL ,行的ctid将会更改。 因此, ctid作为一个长期的行标识符是没有用的。

还有oid但是只有在创build表格时专门请求它才存在。

Postgres文档build议使用数组而不是IN和子查询。 这应该快得多

 DELETE FROM logtable WHERE id = any (array(SELECT id FROM logtable ORDER BY timestamp LIMIT 10)); 

这和其他一些技巧可以在这里find

 delete from logtable where log_id in ( select log_id from logtable order by timestamp limit 10); 

假设你想删除任何10条logging(没有sorting),你可以这样做:

 DELETE FROM logtable as t1 WHERE t1.ctid < (select t2.ctid from logtable as t2 where (Select count(*) from logtable t3 where t3.ctid < t2.ctid ) = 10 LIMIT 1); 

对于我的使用情况,删除10Mlogging,结果是更快。

你可以写一个循环删除各行的过程,程序可以带一个参数来指定要删除的项目的数量。 但是与MySQL相比,这有点矫枉过正。