给定如下表,是否有单一查询方式来更新表:
| 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 |
为此(请注意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 |
我之前看过一些代码,使用了如下所示的@变量,我认为可能有用:
SET @seq = 0;
UPDATE `log` SET `sequence` = @seq := @seq + 1
ORDER BY `created_at`;
但显然不会为每个type_id将序列重置为1.
如果没有单一查询方式可以做到这一点,那么最有效的方法是什么?
此表中的数据可能会被删除,因此我打算在用户完成编辑后运行存储过程以重新排序表。
答案 0 :(得分:5)
您可以使用另一个存储前一个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`;
答案 1 :(得分:0)
我不太了解MySQL,但你可以使用子查询,虽然它可能非常慢。
UPDATE 'log' set 'sequence' = (
select count(*) from 'log' as log2
where log2.type_id = log.type_id and
log2.created_at < log.created_at) + 1
但是,如果两个type_ids具有相同的created_at日期,您将获得重复序列。