3

私はこのテーブルを持っています:

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

この特定のルールを使用して、このテーブルからアイテムを削除する必要があります。

  • それぞれについてrecipient_id、最後に読み取った5つのアイテムを保持し、古い読み取り済みのアイテムを削除します。

私はRECURSIVE WITH声明で心を曲げようとしましたが、惨めに失敗しました。私は自分のソリューションをプログラムで実装しましたが、まともな純粋なSQLソリューションがあるかどうかを知りたいと思いました。

4

3 に答える 3

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;

AJOINは通常、特にアイテムの数が多い場合、IN式よりも高速です。
そしてrow_number()、ではなく、をrank()使用してください!

于 2012-10-11T16:39:11.587 に答える
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
)
于 2012-10-11T16:33:13.553 に答える
0

ウィンドウ関数をチェックしてください:

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
)
于 2012-10-11T16:33:44.440 に答える