开发者

delete old timestamped login history rows from postgresql table

开发者 https://www.devze.com 2023-03-10 17:42 出处:网络
I have a postgresql (v8.4) table with login id and timestamps, and I want to create a batch file that will be run periodically to remove entries when the same id has more than X number of entries in t

I have a postgresql (v8.4) table with login id and timestamps, and I want to create a batch file that will be run periodically to remove entries when the same id has more than X number of entries in the table. Also, the number of entries to keep is stored in a separate table and can be different for each id.

The pertinent columns of the two tables:

CREATE TABLE user_profile (
  id varchar(256) PRIMARY KEY,
  history_count integer
)

CREATE TABLE access_history (
  id varchar(256),
  login_time timestamp
)

The solution I'm contemplating involves 3 SQL commands:

  1. get all login ids with excess entry counts

    SELECT access_history.id, count(*), user_profile.history_count
      FROM d_access_history 
      LEFT JOIN d_user_profile 
      ON access_history.id = user_profile.id 
      GROUP BY access_history.id, user_profile.history_count
      HAVING count(*) > user_profile.history_count;
    
  2. loop through each entry from the above query and get the time stamp for the last entry

    SELECT login_time 
      FROM access_history 
      WHERE id = 'user id'
      ORDER BY login_time DESC 
      OFFSET 200 LIMIT 1;
    
  3. delete entries older then the time stamp retrieved from #2

    DELETE 开发者_JAVA百科from access_history 
      WHERE id = 'user id'
      AND login_time <= '2011-06-06 10:22:29.604156'
    

I am admittedly a novice in SQL, but feel like there must a more efficient way of performing this operation.

thanks in advance


with cte
as
(
    select id, row_number() over (order by login_time desc) RowNumber
    from access_history
)
delete cte
where RowNumber > 200

Replace 200 with the max number of logins you want to keep in history for each user.

[EDIT]

As a_horse_with_no_name mentioned, cte with delete is not supported by 8.4.
You could use delete with a subquery like this.

delete access_history
where id in
(
    select id
    from
    (
        select id, row_number() over (order by login_time desc) RowNumber
        from access_history
    ) tt
    where RowNumber > 200
)
0

精彩评论

暂无评论...
验证码 换一张
取 消