2011-06-07 72 views
3

我有一個postgresql(v8.4)表與登錄ID和時間戳,我想創建一個批處理文件,將定期運行刪除條目,當相同的ID有更多比表中的X個條目少。此外,要保存的條目數存儲在單獨的表中,並且對於每個ID可以不同。從postgresql表中刪除舊的時間戳記登錄歷史行

兩個表的相關列:

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. 得到過量的條目中的所有登錄ID計數

    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. 循環遍歷上述查詢中的每個條目並獲取las的時間戳牛逼進入

    SELECT login_time 
        FROM access_history 
        WHERE id = 'user id' 
        ORDER BY login_time DESC 
        OFFSET 200 LIMIT 1; 
    
  3. 刪除項舊的話,我承認在SQL新手,但感覺像#2

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

檢索到的時間戳有必須在執行的更有效的方法這個操作。

在此先感謝

回答

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

你想在歷史上,以保持每個用戶登錄的最大數量替換200。

[編輯]

如前所述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 
) 
+0

這將需要尚未發佈的版本9.1。 – 2011-06-07 11:00:05

+0

@a_horse_with_no_name - 你確定嗎?我可以看到窗口函數在8.4中可用:http://www.postgresql.org/docs/8.4/interactive/functions-window.html。 – 2011-06-07 15:52:48

+0

是窗口功能可用。但是,在DELETE語句中使用CTE僅在9.1(被稱爲可寫CTE)中受支持。 – 2011-06-07 16:01:18

相關問題