2014-01-08 74 views
1

我在MySQL數據庫中有一個名爲log的表。它用於記錄用戶操作。當它變得非常大時,我想刪除一些記錄。通過限制和條件在MySQL中刪除記錄

SELECT `userid`, `timestamp` 
FROM `log` 
ORDER `timestamp` ASC 

輸出

userid timestamp 
    2 120000 
    3 123333 
    1 123456 
    1 124444 
    2 125555 
    2 126666 
    1 127777 
    1 128888 
    2 129999 
    3 130000 
    1 131111 

我想要做的是 - 我想只保留最後3條爲每個用戶。 因此,我需要刪除每個用戶的第4,第5,...,第n個記錄。 根據上面的示例,希望輸出

userid timestamp 
    3 123333 
    2 125555 
    2 126666 
    1 127777 
    1 128888 
    2 129999 
    3 130000 
    1 131111 

我知道,記錄可以通過使用LIMIT被刪除。

DELETE FROM `log` LIMIT 3 

只刪除3條記錄。它根本無法得到我的願望結果。

我已經試過是

DELETE FROM 
`log` 
WHERE `userid` IN (
SELECT `userid` FROM (SELECT `userid`, COUNT(1) AS C 
FROM `log` 
GROUP BY `userid` 
HAVING C > 3) CountTable) LIMIT 3 

而且這還不是我想要的。

回答

2

試試這個:

DELETE l FROM `log` l 
LEFT JOIN (SELECT l.userid, l.timestamp 
      FROM (SELECT l.userid, l.timestamp, 
         IF(@lastUserId = @lastUserId:=userid, @Idx:[email protected]+1, @Idx:=0) rowNumber 
       FROM `log` l, (SELECT @lastUserId:=0, @Idx:=0) A 
       ORDER BY l.userid, l.timestamp DESC 
       ) AS A 
      WHERE rowNumber < 3 
     ) AS A ON l.userid = A.userid AND l.timestamp = A.timestamp 
WHERE A.userid IS NULL 

編輯:

DELETE l FROM `log` l 
WHERE NOT EXISTS (
      SELECT 1 
      FROM (SELECT l.userid, l.timestamp, 
         IF(@lastUserId = @lastUserId:=userid, @Idx:[email protected]+1, @Idx:=0) rowNumber 
       FROM `log` l, (SELECT @lastUserId:=0, @Idx:=0) A 
       ORDER BY l.userid, l.timestamp DESC 
       ) AS A 
      WHERE l.userid = A.userid AND l.timestamp = A.timestamp AND rowNumber < 3 
     ) 

檢查SQL FIDDLE DEMO

輸出

| USERID | TIMESTAMP | 
|--------|-----------| 
|  3 | 123333 | 
|  2 | 125555 | 
|  2 | 126666 | 
|  1 | 127777 | 
|  1 | 128888 | 
|  2 | 129999 | 
|  3 | 130000 | 
|  1 | 131111 | 
+0

我得到的錯誤'#1064'。我從答案中得到更多的想法。不管怎麼說,還是要謝謝你。 –

+0

@TunZarniKyaw檢查我更新的答案 –

+0

仍然得到錯誤#1064,但是當我嘗試...'SELECT * FROM( SELECT l.userid,l.timestamp,IF(@lastUserId = @lastUserId:= userid,@Idx := @Idx 1,@Idx:= 0)ROWNUMBER FROM日誌升,( SELECT @lastUserId:= 0,@Idx:= 0 )甲 ORDER BY l.userid,l.timestamp DESC )甲 '是好的。它正確顯示'rowNumber'。 –

0

試試下面的SQL:

DELETE FROM log WHERE find_in_set(
    TIMESTAMP, (
     SELECT group_concat(t3) t4 FROM (
      SELECT 1 AS dummy, 
      replace(group_concat(TIMESTAMP ORDER BY TIMESTAMP DESC), concat(SUBSTRING_INDEX(group_concat(TIMESTAMP ORDER BY TIMESTAMP DESC), ',', 3), ','), '') t3 
      FROM log 
      GROUP BY user_id HAVING count(*) > 3 
     ) a GROUP BY dummy 
    ) 
) 

SQL Fiddle