PostgreSQL删除分组依据

时间:2019-04-08 08:50:54

标签: postgresql sql-delete

我有一个PostgreSQL 11数据库。表“ book”的快照如下。我的真实数据库由每个时间戳200行组成,而不是本示例中的四行。

timestamp  ask_price     bid_price
18:00       5                4
18:00       6                3              
18:00       7                2
18:00       8                1
19:00       6                5 
19:00       7                4
19:00       8                3
19:00       9                2

我想删除每个时间戳的前两行以外的所有内容,以减小数据库的大小。结果应如下所示:

timestamp  ask_price     bid_price
18:00       5                4
18:00       6                3              
19:00       6                5 
19:00       7                4

我尝试了以下查询:

DELETE FROM book 
WHERE ctid IN (
SELECT ctid FROM book 
GROUP BY timestamp 
ORDER BY ask_price DESC LIMIT 2)

但是,这将返回以下错误:

ctid must appear in the GROUP BY clause or be used in an aggregate function

如何删除行?

2 个答案:

答案 0 :(得分:1)

您应该使用ROW_NUMBER之类的东西来将每个时间戳将前两行与其余行隔离开来。我们可以尝试以下方法:

DELETE
FROM book b1
USING (
    SELECT ctid,
        ROW_NUMBER() OVER (PARTITION BY timestamp ORDER BY ask_price DESC) rn
    FROM book
) b2
WHERE
    b1.ctid = b2.ctid AND
    b2.rn > 2;

答案 1 :(得分:1)

也要使用类似的东西吗?

CREATE TEMPORARY TABLE temp_table(
   ctid int
);

FOR temprow IN
    SELECT distinct(timestamp) from book
LOOP
    SELECT ctid INTO temp_table FROM book where timestamp = temprow ORDER BY ask_price DESC LIMIT 2 
END LOOP;

DELETE FROM book where ctid IN ( select ctid from temp_table);