patternsqlMinor
MySQL: Keep the 10 most recent rows for each user
Viewed 0 times
rowstherecenteachuserkeepmysqlformost
Problem
I have a table saving scores for a game that have 3 columns (more in practice, but it is easier for everyone this way):
The goal of the query is to delete rows so we have at most 10 scores per user.We also want to keep the most recent rows. So we need to delete the older ones until we get to 10.Note that some players may have less than 10 scores.
How would I manage to do this?
userid : the id of the user that got the score
timestamp: the time the score was gotten
score : the score itselfThe goal of the query is to delete rows so we have at most 10 scores per user.We also want to keep the most recent rows. So we need to delete the older ones until we get to 10.Note that some players may have less than 10 scores.
How would I manage to do this?
Solution
I found figured out an answer that works pretty well, though if you have a lot of users it may take some time to execute. I have yet to do any time testing with it. It also assumes you have an id field that uniquely identifies each score.
The way it works is in the inner query it finds up to the 10 most recent scores. Then deletes everything not returned by the inner query.
The way it works is in the inner query it finds up to the 10 most recent scores. Then deletes everything not returned by the inner query.
DELETE FROM score
WHERE id NOT IN (
SELECT id
FROM (
SELECT *
FROM score s1
WHERE (
SELECT COUNT(*)
FROM score s2
WHERE s1.userid = s2.userid
AND s1.timestamp <= s2.timestamp
) <= 10 --Keep this many records
) foo
);Code Snippets
DELETE FROM score
WHERE id NOT IN (
SELECT id
FROM (
SELECT *
FROM score s1
WHERE (
SELECT COUNT(*)
FROM score s2
WHERE s1.userid = s2.userid
AND s1.timestamp <= s2.timestamp
) <= 10 --Keep this many records
) foo
);Context
StackExchange Database Administrators Q#59238, answer score: 2
Revisions (0)
No revisions yet.