如果count大于,则删除行

时间:2018-04-16 10:28:39

标签: sql postgresql sql-delete

我有用户的事件表,这是我的表格列

events (
  id integer,
  user_id integer,
  event text,
  date timestamp
)

并且当用户的事件数大于100时从表中删除行并开始删除表格中最旧的行。

更新1

适用于PostgreSQL

我想删除当前从用于用户的最旧事件开始的> 100个事件的任何用户的所有事件。所以想为每个用户保留100个最新事件

我尝试使用此查询,但它会永远运行而且不会做任何事情

delete
from events as t1
where id IN (
select id from events where t1.user_id = user_id order by date desc offset 100 
)

更新2

我更新了我的查询并让它运行

delete from events as t
where t.id not in (
   select t2.id
   from events t2
   where t2.user_id = t.user_id
   order by t2.date desc
   limit 100
);

但运行需要11分钟:(我的表有15个用户,71931行,每个用户平均有4795个事件

3 个答案:

答案 0 :(得分:1)

如果要在事件数超过100时删除最旧的行,则只需使用存储过程即可处理此情况。 如果难以连续计算每个条件,则可以简单地使用存储过程。 像下面的代码 我希望您按照以下方式使用它。

1 / 3 = 0.333333333333333314829616256247390992939472198486328125 
3 * (1/3) = 1 
0.999999999999999944488848768742172978818416595458984375
Error on round up 5.5511151231257827021181583404541015625E-17 
Error on round down 5.5511151231257827021181583404541015625E-17 

答案 1 :(得分:0)

使用row_number()功能首先分析数据并删除它们

select * from (
   select *,
        row_number() over (partition by user_id order by date desc) seq 
  from events e
) tt
where seq >= 100

但是,如果您要分析所有events thenremove events子句

,则每个用户的第一个版本都有部门partition

答案 2 :(得分:0)

在大多数SQL版本中,您可以执行以下操作:

delete from t
    where t.date < (select t2.date
                    from t t2
                    where t2.user_id = t.user_id
                    order by t2.date desc
                    offset 99 fetch first 1 row only
                   );

或者:

delete from t
    where t.date not in (select t2.date
                         from t t2
                         where t2.user_id = t.user_id
                         order by t2.date desc
                         fetch first 100 row only
                        );