重新排序MYSQL表

时间:2013-09-15 11:06:24

标签: mysql sql database select sql-order-by

我有一个带有'Order'字段的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

我可以通过记录来做这个记录

按订单顺序获取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

3 个答案:

答案 0 :(得分: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)
                 );

答案 1 :(得分:0)

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

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

SELECT * FROM MyTable WHERE mycolumn = 'MyCondition' ORDER BY order;

答案 2 :(得分: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。*不是必需的 - 只有用于最终连接的字段。

我的例子假设要更新的字段称为Sequence(意图可能比订单更清晰,但主要是回避保留的关键字问题)

我花了一段时间才得到原始答案中的“const”不是MySQL关键字。 (由于这个原因,我从来不是缩写的粉丝 - 有时可以通过多种方式解释,特别是在最好的时候,它们最好不要被误解。使用冗长的代码我知道,但清晰度总是胜过我书中的便利性。 )

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

此更新的值当然是对所有相关行的原子更新,而不是实际数据拉取和逐行更新单行。

我的下一个问题,这应该不难确定,但我已经了解到SQL在最好的时候可以成为一种技巧,就是看看这是否可以在数据子集上安全地完成。 (其中某些originalTable.parentID是一个设定值)。