Reputation: 2706
Currently I am using the following solution to check number of records and then delete the last one of them which is over the limit. Pseudocode:
var count = SELECT COUNT(*) AS count FROM table WHERE user_id = ?;
if (count > LIMIT) { // e.g [LIMIT == 5]
DELETE FROM table WHERE user_id = ? ORDER BY last_activity LIMIT 1;
}
The problem however is that I am not happy about this solution. I would like to or rather prefer to do all this using one sql query only.
The type of last_activity
column is DATETIME
.
Upvotes: 0
Views: 99
Reputation: 49049
To keep everything in a single query, you could use something like this:
DELETE FROM table
WHERE
user_id = ?
AND last_activity = (SELECT * FROM
(SELECT CASE WHEN COUNT(*)>5 THEN MIN(last_activity) END
FROM table
WHERE user_id = ?) s)
subquery will return the first last_activity
if there are more than 5 activities, and the DELETE query will delete it. Otherwise it will return NULL and no row will be deleted.
Upvotes: 0
Reputation: 1269693
You can use join
in a delete
statement to delete all but the most recent row, when there are more than five rows for a user:
delete t from table t join
(select user_id, max(last_activity) as mla
from table
group by user_id
having count(*) > 5
) mla
on t.user_id = mla.user_id and
t.last_activity < mla.mla;
That does it for all users. For one user, add a where
statement:
delete t from table t join
(select user_id, max(last_activity) as mla
from table
where user_id = '?'
group by user_id
having count(*) > 5
) mla
on t.user_id = mla.user_id and
t.last_activity < mla.mla;
EDIT:
To delete one row, just use min()
instead of max()
:
delete t from table t join
(select user_id, min(last_activity) as mla
from table
where user_id = '?'
group by user_id
having count(*) > 5
) mla
on t.user_id = mla.user_id and
t.last_activity = mla.mla;
Upvotes: 1