我有一个类似于以下内容的表:
| id | sub_id | fk_id |
|----|--------|-------|
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 3 | 1 |
| 4 | 4 | 1 |
| 5 | 5 | 1 |
| 6 | 1 | 2 |
| 7 | 2 | 2 |
| 8 | 3 | 2 |
| 9 | 4 | 2 |
| 10 | 5 | 2 |
在此表中,id
是主键,sub_id
和fk_id
构成复合唯一键,其中fk_id
是另一个表中的主键。< / p>
我发现自己处于需要能够删除表中行的情况,但是重新编号sub_id以便没有任何间隙,例如移除(1, 1, 1)
以及fk_id=1
各自sub_id
重新编号为1,2,3,4等的所有行
我还需要能够一次删除一行或多行,然后触发重新编号(因为我认为只要一次就足够多次尝试重新编号,效率很低)。但是,fk_id
的每个值最多有60行,但fk_id
可能有数千个不同的值。
我应该如何进行重新编号?我认为某种INSERT ... SELECT查询,但我无法理解它应该如何工作。
答案 0 :(得分:0)
您可以使用此查询对给定fk_id
的行重新编号:
select t_renum.*, count(t_lower.id) as new_sub_id
from mytable t_renum
join mytable t_lower
on t_lower.fk_id = t_renum.fk_id
and t_lower.id <= t_renum.id
where t_renum.fk_id = @renumber_fk_id
group by t_renum.id
结果可以与原始表一起进行更新,如下所示:
update mytable t
join (
select t_renum.*, count(t_lower.id) as new_sub_id
from mytable t_renum
join mytable t_lower
on t_lower.fk_id = t_renum.fk_id
and t_lower.id <= t_renum.id
where t_renum.fk_id = @renumber_fk_id
group by t_renum.id
) t_renum using (id)
set t.sub_id = t_renum.new_sub_id
答案 1 :(得分:0)
在深入挖掘之后,我发现另一个非常简单的answer并且避免了在许多类似问题中推荐的新表的需要。我把它转换成了一个更符合我需求的存储过程:
DELIMITER //
CREATE PROCEDURE reindex (IN fk_key INT UNSIGNED)
BEGIN
SET @num := 0;
UPDATE example
SET sub_id = (@num := @num + 1)
WHERE fk_id = fk_key
ORDER BY id;
END //
DELIMITER ;