0

我有一个带有“订单”字段的 MySql 表,但是当一条记录被删除时,会出现一个空白,如何按顺序更新我的“订单”字段?如果可能在一个查询中 1 1

id.........order
1...........1
5...........2
4...........4
3...........6
5...........8

id.........order
1...........1
5...........2
4...........3
3...........4
5...........5

我可以逐条记录

获取按 Order 排序的 SELECT 并逐行更改 Order 字段,但老实说我不喜欢它。

谢谢

额外信息:

我也想这样改变它:

id.........order
1...........1
5...........2
4...........3
3...........3.5
5...........4

id.........order
1...........1
5...........2
4...........3
3...........4
5...........5
4

3 回答 3

4

在 MySQL 中,您可以这样做:

update t join
       (select t.*, (@rn := @rn + 1) as rn
        from t cross join
             (select @rn := 0) const
        order by t.`order`
       ) torder
       on t.id = torder.id
    set `order` = torder.rn;

在大多数数据库中,您也可以使用相关子查询来执行此操作。但这在 MySQL 中可能是个问题,因为它不允许将表作为子查询进行更新:

update t
    set `order` = (select count(*)
                   from t t2
                   where t2.`order` < t.`order` or
                         (t2.`order` = t.`order` and t2.id <= t.id)
                 );
于 2013-09-15T12:17:29.923 回答
0

无需重新编号或重新订购。该表只是为您提供所有数据。如果您需要它以某种方式呈现,那就是查询的工作。

您甚至不需要更改查询中的订单值,只需执行以下操作:

SELECT * FROM MyTable WHERE mycolumn = 'MyCondition' ORDER BY order;
于 2013-09-15T11:16:59.437 回答
0

上面的答案非常好,但我花了一段时间才理解它,所以我提供了一个轻微的重写,我希望能更快地让其他人更清楚:

update 
   originalTable 
   join (select originalTable.ID, 
      (@newValue := @newValue + 10) as newValue 
   from originalTable 
   cross join (select @newValue := 0) newTable
   order by originalTable.Sequence) 
   originalTable_reordered 
   on originalTable.ID = originalTable_reordered.ID 
set originalTable.Sequence = originalTable_reordered.newValue;

请注意 originalTable.* 不是必需的 - 仅用于最终连接的字段。

我的示例假设要更新的字段称为序列(可能意图比顺序更清晰,但主要回避保留关键字问题)

我花了一段时间才明白原来答案中的“const”不是 MySQL 关键字。(出于这个原因,我从不喜欢缩写词 - 有时可以以多种方式解释,尤其是在最好不要被误解的情况下。使我知道冗长的代码,但在我的书中,清晰总是胜过便利。 )

不太确定 select @newValue := 0 的用途是什么,但我认为这是必须在以后使用变量之前表达变量的副作用。

此更新的价值当然是对所有相关行的原子更新,而不是进行数据拉取并务实地逐一更新单行。

我的下一个问题应该不难确定,但我了解到 SQL 在最好的情况下可能是一个诡计,是看看这是否可以安全地在数据子集上完成。(其中一些 originalTable.parentID 是一个设定值)。

于 2015-03-12T16:06:32.590 回答