我有一个包含6列的user_accounts表:
id, user_id, amount, type, total_balance, created_at
1 101 10 debit 90 2018-09-14 20:10:49
2 101 30 credit 120 2018-09-14 20:10:52
3 102 210 credit 310 2018-09-14 21:10:52
4 102 10 debit 300 2018-09-14 21:10:54
5 103 10 credit 110 2018-09-14 21:10:54
6 104 15 credit 115 2018-09-14 21:11:59
我想保留每个用户的最新n行,并删除其余行。
在mysql
中构造此查询的最佳方法是什么?
答案 0 :(得分:1)
您可以尝试在子查询中按每个userId设置行号,并按created_at
排序。
然后通过ID
删除每个userId上的rn
根据我的示例,我只保留第一行,所以我设置了rn > 1
CREATE TABLE T(
id int,
user_id int,
amount int,
type varchar(50),
total_balance int,
created_at datetime
);
insert into T values (1,101,10 ,'debit',90 ,'2018-09-14 20:10:49');
insert into T values (2,101,30 ,'credit',120,'2018-09-14 20:10:52');
insert into T values (7,101,30 ,'credit',120,'2018-09-16 20:10:52');
insert into T values (3,102,210,'credit',310,'2018-09-14 21:10:52');
insert into T values (4,102,10 ,'debit',300,'2018-09-14 21:10:54');
insert into T values (5,103,10 ,'credit',110,'2018-09-14 21:10:54');
insert into T values (6,104,15 ,'credit',115,'2018-09-14 21:11:59');
DELETE FROM T
WHERE ID IN (
SELECT ID
FROM
(
SELECT ID,(
SELECT COUNT(*)
FROM T tt
WHERE
tt.user_id = t1.user_id
AND
tt.created_at >= t1.created_at
ORDER BY
tt.created_at desc
) rn
FROM T t1
) deltable
where rn > 1 # n least rows you want to keep.
);
查询1 :
SELECT * FROM T
Results :
| id | user_id | amount | type | total_balance | created_at |
|----|---------|--------|--------|---------------|----------------------|
| 7 | 101 | 30 | credit | 120 | 2018-09-16T20:10:52Z |
| 4 | 102 | 10 | debit | 300 | 2018-09-14T21:10:54Z |
| 5 | 103 | 10 | credit | 110 | 2018-09-14T21:10:54Z |
| 6 | 104 | 15 | credit | 115 | 2018-09-14T21:11:59Z |
答案 1 :(得分:0)
您可以尝试以下查询。这里N是您要保留的行数
DELETE FROM user_accounts WHERE id NOT IN (select id FROM user_accounts ORDER BY created_at DESC LIMIT N)
答案 2 :(得分:0)
这将适用于记录最近的3条记录:
create table ns_t(t timestamp);
desc ns_t;
insert into ns_t values(current_timestamp);
insert into ns_t values(current_timestamp + INTERVAL '2' HOUR);
insert into ns_t values(current_timestamp + INTERVAL '4' HOUR);
insert into ns_t values(current_timestamp + INTERVAL '8' HOUR);
insert into ns_t values(current_timestamp + INTERVAL '10' HOUR);
insert into ns_t values(current_timestamp + INTERVAL '12' HOUR);
select * from (select * from ns_t order by t desc) where rownum<=3;