给定如下表,是否有单一查询方式来更新表:
| id | type_id | created_at | sequence |
|----|---------|------------|----------|
| 1 | 1 | 2010-04-26 | NULL |
| 2 | 1 | 2010-04-27 | NULL |
| 3 | 2 | 2010-04-28 | NULL |
| 4 | 3 | 2010-04-28 | NULL |
Run Code Online (Sandbox Code Playgroud)
对此(注意created_at用于排序,并sequence"按"分组type_id):
| id | type_id | created_at | sequence |
|----|---------|------------|----------|
| 1 | 1 | 2010-04-26 | 1 |
| 2 | 1 | 2010-04-27 | 2 |
| 3 | 2 | 2010-04-28 | 1 |
| 4 | 3 | 2010-04-28 | 1 |
Run Code Online (Sandbox Code Playgroud)
我之前看过一些代码使用了@变量,如下所示,我认为可能有用:
SET @seq = 0;
UPDATE `log` SET `sequence` = @seq := @seq + 1
ORDER BY `created_at`;
Run Code Online (Sandbox Code Playgroud)
但是,对于每个type_id,这显然不会将序列重置为1.
如果没有单一查询方式来做到这一点,那么最有效的方法是什么?
此表中的数据可能会被删除,因此我计划在用户完成编辑后运行存储过程以重新排序表.
您可以使用另一个存储前一个type_id(@type_id)的变量.查询按顺序排列type_id,因此每当有变化时type_id,必须再次将序列重置为1.
Set @seq = 0;
Set @type_id = -1;
Update `log`
Set `sequence` = If(@type_id=(@type_id:=`type_id`), (@seq:=@seq+1), (@seq:=1))
Order By `type_id`, `created_at`;
Run Code Online (Sandbox Code Playgroud)