我在一个MySQL数据库中有一个名为log
的表。它用于记录用户操作。当它变得非常大时,我想删除一些记录。
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
这不是我想要的。
答案 0 :(得分:2)
试试这个:
DELETE l FROM `log` l
LEFT JOIN (SELECT l.userid, l.timestamp
FROM (SELECT l.userid, l.timestamp,
IF(@lastUserId = @lastUserId:=userid, @Idx:=@Idx+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:=@Idx+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
)
<强>输出强>
| USERID | TIMESTAMP |
|--------|-----------|
| 3 | 123333 |
| 2 | 125555 |
| 2 | 126666 |
| 1 | 127777 |
| 1 | 128888 |
| 2 | 129999 |
| 3 | 130000 |
| 1 | 131111 |
答案 1 :(得分: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
)
)