我在 mySql 中有一个记录表。我需要维护用户指定的订单。所以我添加了一个“位置”列。
当我移动特定记录时,更新所有记录的 SQL 语句是什么?我有类似的东西:
UPDATE items SET position = '2' WHERE id ='4';
UPDATE items SET position = position+1 WHERE position >= '2' AND id != '4';
但是,如果记录下降,大于将是小于。有什么诀窍?谢谢!
我在 mySql 中有一个记录表。我需要维护用户指定的订单。所以我添加了一个“位置”列。
当我移动特定记录时,更新所有记录的 SQL 语句是什么?我有类似的东西:
UPDATE items SET position = '2' WHERE id ='4';
UPDATE items SET position = position+1 WHERE position >= '2' AND id != '4';
但是,如果记录下降,大于将是小于。有什么诀窍?谢谢!
这样的事情会做吗?
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 );
我测试了几次,它似乎工作。
对例如由用户维护行号的销售订单执行此类操作,我发现最好在 BL 或 UI 中的数组中处理它。通常他们会想调整几条记录,有时想说“算了”。因此,最简单的方法可能是等到他们点击“确定”按钮(或您的等效按钮),然后按照当前顺序将它们全部写回。
您最终也可能会处理删除问题,这是您可以以相同方式处理的另一个问题。
这是我对此的看法:我的 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_indexes 搞砸了。要解决此问题,请执行以下两个查询:
SET @pos:=-10;
UPDATE your_table SET row_index = @pos:=@pos+10 WHERE ...
这将更新您的所有行(或您使用 where 语句选择的行)并设置 row_index 列没有间隙(0、10、20、30,ecc.)。当然,这种方式会增加写入操作的负载,但我认为这是在读取操作期间获取订单的最快方式。如果您删除一行,您可以重新运行修复订单查询。
我建议至少在项目之间使用较大的增量(例如 10000)。然后只是做一个订单。如果您需要将 11000 移动到 9000 和 10000 之间,那么只需将其设置为 9500 即可。
这并没有消除重新排序的问题,但它大大减少了它。在某些时候,您最好删除所有行,然后以正确的顺序读取它们。像您一样进行更新太容易出错恕我直言。
您可能会考虑使用链表类型的方法,用一个键指向下一个,也可能是列表中的上一个项目,然后您只需更新几条记录,而不是全部更新。
有趣的!好的,所以没有简单的答案。我以为我只是错过了一些东西。我考虑过维护一个外部数组。这听起来像是最好的主意。
也许是这样的?
$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