2014-01-08 38 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