如何限制每个所有者标识在数据库中的行数

How to limit number of rows in a database for each owner id

我需要为 Postgres 创建一个复杂的 SQL 语句,我似乎无法理解,有人能帮我解决这个问题吗?这是我需要的:

我有一个名为 tags 的 table,它是一个存储名称和值的 table,以及拥有标签的用户 ID 和 ID 等信息标签本身。对于此问题的上下文,您只需要了解以下列:

我需要允许版主将公会中每个用户的所有多余标签删除到特定限制,首先优先处理较旧的标签。例如,假设这是我的 table:

 id |      guild_id      |      owner_id      |         created_at
----+--------------------+--------------------+----------------------------
 14 | 715039810976219206 | 322896727071784960 | 2022-03-30 21:47:36.81417
 17 | 715039810976219206 | 600855080962490396 | 2022-03-31 00:57:18.024558
 20 | 715039810976219206 | 322896727071784960 | 2022-03-31 01:03:57.586239
 21 | 715039810976219206 | 322896727071784960 | 2022-03-31 01:35:13.426953
 22 | 715039810976219206 | 322896727071784960 | 2022-04-14 02:02:46.852122
 25 | 715039810976219206 | 322896727071784960 | 2022-04-14 02:03:13.559069
 26 | 239865610974543234 | 322896727071784960 | 2022-04-14 02:03:18.885876

当版主尝试以 3 的限制和 715039810976219206 的公会执行此功能时,它将执行以下操作:

我已经尝试了一段时间了,如果有帮助的话,这是我到目前为止所得到的:

DELETE FROM tags
WHERE id IN (
    SELECT id FROM tags
    WHERE guild_id =  AND owner_id = ???? ORDER BY created_at DESC
    OFFSET 
);

(那个????是因为我完全失去了我在做什么)

希望我已经解释清楚,让您能够理解。任何帮助将不胜感激,如果可能的话,对答案的解释将很有帮助。

如果我对你的问题的理解正确,你可以使用 rank() 函数并按 owner_id 对它们进行分组,然后按分区日期排序。然后删除所有排名高于 3 的记录。

DELETE FROM  tags WHERE id in (
  SELECT id FROM 
  (
    SELECT id, 
           owner_id,
           rank() over (partition by owner_id order by created_at desc) as rnk
    FROM tags
  ) as t
  WHERE t.rnk > 3
 );
 
 SELECT * FROM tags

db fiddle link