SQL:忽略一些返回的行,删除其他行

时间:2012-10-11 16:26:32

标签: sql postgresql window-functions

我有这张桌子:

| Column        | Type                           |
+---------------+--------------------------------+         
| id            | integer                        |
| recipient_id  | integer                        | 
| is_read       | boolean                        | 
| updated_at    | timestamp(0) without time zone | 

我必须使用以下特定规则从此表中删除项目:

  • 对于每个recipient_id,我们会保留最后读取的5个项目,并删除旧的读取项目。

我试图用RECURSIVE WITH语句来改变主意,但却失败了。我已经以编程方式实现了我的解决方案,但我想知道是否有一个不错的纯SQL解决方案。

3 个答案:

答案 0 :(得分:2)

DELETE FROM tbl t
USING (
    SELECT id, row_number() OVER (PARTITION BY recipient_id
                                  ORDER BY updated_at DESC) as rn
    FROM   tbl
    WHERE  is_read
  ) x
WHERE  x.rn > 5
AND    x.id = t.id;

JOIN通常比IN表达式快,尤其是项目数量较多时 并使用row_number(), not rank()

答案 1 :(得分:0)

delete from t
where id in (
    select id
    from (
        select 
            id, 
            row_number() over(partition by recipient_id order by updated_at desc) rn
        from t
        where is_read
    ) s
    where s.rn > 5
)

答案 2 :(得分:0)

结帐window functions

DELETE FROM table
WHERE id IN (
  SELECT id
  FROM (
    SELECT id, rank() OVER (PARTITION BY recipient_id ORDER BY updated_at DESC) as position
    FROM table
    WHERE is_read
  ) subselect WHERE position > 5
)