维护/更新mysql中的记录顺序

时间:2009-01-26 23:16:11

标签: mysql sorting sql-update

我在mySql中有一个记录表。我需要维护用户指定的订单。所以我添加了一个“位置”列。

移动特定记录时更新所有记录的SQL语句是什么?我有类似的东西:

UPDATE items SET position = '2' WHERE id ='4';
UPDATE items SET position = position+1 WHERE position >= '2' AND id != '4';

但是,如果记录下降,那么大于将会更大。有什么诀窍?谢谢!

7 个答案:

答案 0 :(得分:7)

这样的事情可以吗?

UPDATE items 
SET position = CASE position 
  WHEN $oldpos THEN $newpos 
  ELSE position + SIGN($oldpos-$newpos)
 END
WHERE position BETWEEN LEAST( $newpos, $oldpos ) 
                AND GREATEST( $newpos, $oldpos );

我测试了几次,似乎有效。

答案 1 :(得分:2)

做这种事情,例如用户维护的行号的销售​​订单,我发现最好在BL或UI的数组中处理它。通常他们会想要调整几个记录,有时想说“忘记它”。所以最简单的可能是等到他们点击“确定”按钮(或你的等价物),然后用当前的顺序将它们全部写回来。

你也可能最终处理删除,这是另一个你可以用同样方法处理的问题。

答案 2 :(得分:1)

这是我对此的看法:我的row_index列的数字步长为10(例如:0,10,20,ecc。)。当用户更新其中一行时,您需要知道它是上升还是下降。如果必须将第2行移动到第4行(向下,所需的row_index = 30),则将row_index设置为35;否则(如果上升)将其设置为25.设置此值:

UPDATE your_table SET row_index = 35 WHERE your_id = 1234

现在你有正确的顺序,但是row_indexs搞砸了。要解决此问题,请执行以下两个查询:

SET @pos:=-10;
UPDATE your_table SET row_index = @pos:=@pos+10 WHERE ...

这将更新所有行(或使用where语句选择的行)并设置row_index列,不带间隙(0,10,20,30,ecc。)。当然这种方式会增加写操作的负担,但我认为这是在读操作期间获取订单的最快方法。如果删除一行,则可以重新运行修订订单查询。

答案 3 :(得分:0)

我建议,至少在项目之间使用大增量(比如10000)。然后只是做一个订单。如果你需要将11000移动到9000到10000之间,那么只需将其设置为9500并完成。

这并没有消除重新排序的问题,但它大大减少了它。在某些时候,你最好删除所有行,然后用正确的顺序读取它们。像你这样做的更新太容易出错了。

答案 4 :(得分:0)

您可以考虑使用链接列表类型的方法,使用下一个键,也可能是列表中的上一个项,然后您只需要更新一些记录,而不是所有记录。

答案 5 :(得分:0)

有趣!好的,所以没有简单的答案。我以为我只是遗漏了一些东西。我想过维护一个外部阵列。这听起来像是最好的主意。

答案 6 :(得分:0)

也许是这样的?

$item_id = $_GET['item_id']; 
$position = $_GET['new_position']; 
$old_position = $_GET['old_position'];

if($new_position < $old_position) {
    SQL: UPDATE items SET position = position+1 WHERE position >= $new_position AND position < $old_position  
} else {  
SQL: UPDATE items SET position = position-1 WHERE position <= $new_position AND position > $old_position
}  

SQL: UPDATE items SET position = $new_position WHERE item_id = $item_id