我正在尝试删除除最后3个以外的所有记录。
每个记录都有一个名为slug和version的列。
这里的slug名称可以相同,但版本号是唯一的。
For example.
slug version
template1 1
template1 2
template1 3
template1 4
template1 5
template1 6
我想保留最后3条记录4,5,6并删除其余的1,2,3
使用存储过程尝试了以下方法。
CREATE DEFINER=`root`@`localhost` PROCEDURE `deleteall`()
BEGIN
DELETE FROM `table_name` WHERE slug='template1' and version IN(
SELECT version
FROM (
SELECT version
FROM `table_name`
ORDER BY version asc
LIMIT 3 offset 3
) tbl123
);
END
提前致谢。
答案 0 :(得分:1)
将asc更改为desc并将限制增加到大数
create table t(slug varchar(20), version int);
insert into t values
('template1' , 1),
('template1' , 2),
('template1' , 3),
('template1' , 4),
('template1' , 5),
('template1' , 6),
('template1' , 7);
delete from t where version in
(
select version from
(
SELECT version
FROM t
ORDER BY version desc
LIMIT 999999 offset 3
) s
);
+-----------+---------+
| slug | version |
+-----------+---------+
| template1 | 5 |
| template1 | 6 |
| template1 | 7 |
+-----------+---------+
3 rows in set (0.00 sec)
如果要将slug作为参数传递给存储过程
drop table if exists t;
create table t(slug varchar(20), version int);
insert into t values
('template1' , 1),
('template1' , 2),
('template1' , 3),
('template1' , 4),
('template1' , 5),
('template1' , 6),
('template1' , 7),
('template2' , 1),
('template2' , 2),
('template2' , 3),
('template2' , 4),
('template3' , 1),
('template3' , 2),
('template3' , 3);
drop procedure if exists p;
delimiter $$
create procedure p(inslug varchar(100))
begin
delete from t where slug = inslug and version in
#select * from t where slug = inslug and version in
(
select version from
(
SELECT version
FROM t
where slug = inslug
ORDER BY version desc
LIMIT 999999 offset 3
) s
);
end $$
delimiter ;
MariaDB [sandbox]> call p('template2');
Query OK, 1 row affected (0.02 sec)
MariaDB [sandbox]> select * from t;
+-----------+---------+
| slug | version |
+-----------+---------+
| template1 | 1 |
| template1 | 2 |
| template1 | 3 |
| template1 | 4 |
| template1 | 5 |
| template1 | 6 |
| template1 | 7 |
| template2 | 2 |
| template2 | 3 |
| template2 | 4 |
| template3 | 1 |
| template3 | 2 |
| template3 | 3 |
+-----------+---------+
13 rows in set (0.00 sec)
MariaDB [sandbox]> call p('template1');
Query OK, 4 rows affected (0.02 sec)
MariaDB [sandbox]> select * from t;
+-----------+---------+
| slug | version |
+-----------+---------+
| template1 | 5 |
| template1 | 6 |
| template1 | 7 |
| template2 | 2 |
| template2 | 3 |
| template2 | 4 |
| template3 | 1 |
| template3 | 2 |
| template3 | 3 |
+-----------+---------+
9 rows in set (0.00 sec)
MariaDB [sandbox]> call p('template3');
Query OK, 0 rows affected (0.00 sec)
MariaDB [sandbox]> select * from t;
+-----------+---------+
| slug | version |
+-----------+---------+
| template1 | 5 |
| template1 | 6 |
| template1 | 7 |
| template2 | 2 |
| template2 | 3 |
| template2 | 4 |
| template3 | 1 |
| template3 | 2 |
| template3 | 3 |
+-----------+---------+
9 rows in set (0.00 sec)
如果你想删除所有slug(通过迭代光标)或只删除一个
drop procedure if exists p;
delimiter $$
create procedure p(inslug varchar(100))
begin
declare vslug varchar(100) default false;
declare done int;
declare cur cursor for select distinct slug from t;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
if inslug <> 'all' then
delete from t where slug = inslug and version in
#select * from t where slug = inslug and version in
(
select version from
(
SELECT version
FROM t
where slug = inslug
ORDER BY version desc
LIMIT 999999 offset 3
) s
);
else
open cur;
read_loop: loop
fetch cur into vslug;
if done then leave read_loop; end if;
delete from t where slug = vslug and version in
#select * from t where slug = vslug and version in
(
select version from
(
SELECT version
FROM t
where slug = vslug
ORDER BY version desc
LIMIT 999999 offset 3
) s
);
end loop;
close cur;
end if;
end $$
delimiter ;
并通过电话(&#39;所有&#39;)或致电(特定slu)来运行