удалить старые строки истории входа с метками времени из таблицы postgresql - PullRequest
3 голосов
/ 07 июня 2011

У меня есть таблица postgresql (v8.4) с идентификатором входа в систему и временными метками, и я хочу создать пакетный файл, который будет периодически запускаться для удаления записей, когда один и тот же идентификатор имеет более X количества записей в таблице.Кроме того, количество сохраняемых записей хранится в отдельной таблице и может быть разным для каждого идентификатора.

Соответствующие столбцы двух таблиц:

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

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

Решение, которое я имеюРассмотрение включает в себя 3 команды SQL:

  1. получить все идентификаторы входа с избыточным количеством записей

    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. перебрать каждую запись из вышеприведенного запроса иполучить отметку времени для последней записи

    SELECT login_time 
      FROM access_history 
      WHERE id = 'user id'
      ORDER BY login_time DESC 
      OFFSET 200 LIMIT 1;
    
  3. удалить записи старше, чем отметка времени, полученная из # 2

    DELETE from access_history 
      WHERE id = 'user id'
      AND login_time <= '2011-06-06 10:22:29.604156'
    

IПо общему признанию, я новичок в SQL, но чувствую, что должен быть более эффективный способ выполнения этой операции.

заранее спасибо

1 Ответ

2 голосов
/ 07 июня 2011
with cte
as
(
    select id, row_number() over (order by login_time desc) RowNumber
    from access_history
)
delete cte
where RowNumber > 200

Замените 200 на максимальное количество логинов, которые вы хотите сохранить в истории для каждого пользователя.

[EDIT]

Как упомянуто a_horse_with_no_name, cteс удалением не поддерживается 8.4.
Вы можете использовать удаление с таким подзапросом, как этот.

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
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...