是否有单个查询可以更新多个组的“序列号”?

时间:2010-04-30 10:00:39

标签: sql mysql

给定如下表,是否有单一查询方式来更新表:

| 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用于排序,sequencetype_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.

如果没有单一查询方式可以做到这一点,那么最有效的方法是什么?

此表中的数据可能会被删除,因此我打算在用户完成编辑后运行存储过程以重新排序表。

2 个答案:

答案 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日期,您将获得重复序列。