简体   繁体   English

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

[英]Maintaining/updating record order in mysql

I have a table of records in mySql. 我在mySql中有一个记录表。 I need to maintain an order for them as specified by the user. 我需要维护用户指定的订单。 So I've added a 'position' column. 所以我添加了一个“位置”列。

What would be the SQL statement to update all the records when I move a specific record? 移动特定记录时,更新所有记录的SQL语句是什么? I've got something like: 我有类似的东西:

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

But the greater than is going to be a less than if the record has moved down. 但是,如果记录下降,那么大于将会更大。 What's the trick? 有什么诀窍? Thanks! 谢谢!

Would something like this do it? 这样的事情会这样吗?

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 );

I tested it a couple of times and it seems to work. 我测试了几次它似乎工作。

Doing this sort of thing for eg sales orders with line numbers maintained by the user, I've found it best to handle it in an array in the BL or UI. 对于例如用户维护的行号的销售​​订单执行此类操作,我发现最好在BL或UI中的数组中处理它。 Usually they will want to adjust several records, and sometimes want to say "forget it". 通常他们会想要调整几个记录,有时想说“忘记它”。 So the easiest might be to just wait until they hit the "OK" button (or your equivalent) and then write them all back with current ordering. 所以最简单的可能就是等到它们点击“OK”按钮(或你的等效按钮),然后用当前的顺序将它们全部写回来。

You may end up dealing with deletions, too, which is another problem you can handle the same way. 您最终也可能会处理删除操作,这是您可以采用相同方式处理的另一个问题。

This is my take on this: my row_index column has number with a step of 10 (eg.: 0, 10, 20, ecc.). 这是我对此的看法:我的row_index列的数字步长为10(例如:0,10,20,ecc。)。 When a user updates one of the row you need to know if it's going up or down. 当用户更新其中一行时,您需要知道它是上升还是下降。 If you have to move the 2nd row to the 4th (going down, desired row_index = 30), you set the row_index to 35; 如果必须将第2行移动到第4行(向下,所需的row_index = 30),则将row_index设置为35; otherwise (if going up) set it to 25. Set this value: 否则(如果上升)将其设置为25.设置此值:

UPDATE your_table SET row_index = 35 WHERE your_id = 1234

Now you have the correct order, but the row_indexes are messed up. 现在你有正确的顺序,但是row_indexs搞砸了。 To fix this, execute this two queries: 要解决此问题,请执行以下两个查询:

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

This is going to update all your rows (or the one you select with the where statement) and set the row_index column without gaps (0, 10, 20, 30, ecc.). 这将更新您的所有行(或您使用where语句选择的行)并设置row_index列没有间隙(0,10,20,30,ecc。)。 Surely this way adds load on the write operations, but I think it's the fastest way to get the order during read operations. 当然这种方式会增加写操作的负担,但我认为这是在读操作期间获取订单的最快方法。 If you delete a row you can just re run the fixing order queries. 如果删除行,则可以重新运行修订订单查询。

Maybe something like this? 也许是这样的?

$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 

I would suggest, at a minimum, using large increments (say 10000) between items. 我建议,至少在项目之间使用大增量(比如10000)。 Then just doing an order by. 然后只是做一个订单。 If you need to move 11000 to between 9000 and 10000 then just set it to 9500 and done. 如果您需要将11000移动到9000到10000之间,那么只需将其设置为9500即可完成。

This doesn't eliminate the problem of reordering but it greatly reduces it. 这并没有消除重新排序的问题,但它大大减少了它。 At some point you're better off deleting all the rows then readding them with the correct order. 在某些时候,你最好删除所有行,然后用正确的顺序读取它们。 Doing updates like you're doing is just too error prone imho. 做你喜欢的更新太容易出错了。

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

Interesting! 有趣! Okay, so there is no easy answer. 好的,所以没有简单的答案。 I thought I was just missing something. 我以为我只是遗漏了一些东西。 I'd thought about maintaining an external array. 我想过维护一个外部阵列。 That sounds like the best idea. 这听起来像是最好的主意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM