postgresql 如何在Postgres中删除表格中最旧的X项?

yhxst69z  于 2023-01-17  发布在  PostgreSQL
关注(0)|答案(4)|浏览(134)

我正在尝试实现一个滚动版本系统,用户可以保留某个东西的几个版本,但是一旦超过10个版本,它就会删除最旧的项目。
这就是我想要做的,但是语法是无效的(不能在LIMIT中使用行计数):

with version_ids as (
  select rd.id from reels_data rd, reels r where r.owner_id = '7f92dcc6-f906-418a-aee0-074b297bfb52' and reel_id = 40 order by version
)
delete from reels_data where id in (select id, count(*) as rows from version_ids limit 10 - rows);

关于Postgres,我还有很多不知道的地方,所以我想有一些更好的方法可以做到这一点。

ie3xauqp

ie3xauqp1#

如果我没理解错的话,你可以按降序列出一个用户的现有版本,跳过前10个(即最新的10个),删除剩下的:

DELETE FROM reels_data
WHERE id IN (
    SELECT id
    FROM reels
    WHERE reels.owner_id = '7f92dcc6-f906-418a-aee0-074b297bfb52'
    ORDER BY version DESC /* assuming no null versions */
    OFFSET 10
)

如果用户拥有的版本少于10个,OFFSET将不会返回(和删除)任何内容。
如果您希望在单个查询中为多个用户执行此操作,则需要使用窗口函数(可能是rank()row_number())。

bogh5gae

bogh5gae2#

如果你只想保留10个新的:

  • 通过按版本排序并使用LIMIT选择10个较新的ID
  • 从表中删除所有ID不在所选范围内的项
z18hc3ub

z18hc3ub3#

我认为你想要:

delete from reels_data rd
    where rd.id < (select rd2.id
                   from reels_data rd2
                   where rd2.owner = rd.owner
                   order by rd2.id desc
                   limit 1 offset 9
                  );

子查询获取每个所有者的第10个最大值id。任何较小的值都将被删除。如果不是10个,则子查询返回NULL,并且不删除该所有者的任何内容。

piwo6bdm

piwo6bdm4#

NOT IN比马斯的快得多:

DELETE FROM tableName
WHERE id NOT IN (
    SELECT id
    FROM tableName
    ORDER BY id DESC
    LIMIT 10
)

相关问题