我有一个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
如何删除行?
答案 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);