Pregunta

Tengo una tabla de registros en mySql. Necesito mantener un orden para ellos según lo especificado por el usuario. Entonces agregué una columna de 'posición'.

¿Cuál sería la instrucción SQL para actualizar todos los registros cuando muevo un registro específico? Tengo algo como:

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

Pero cuanto mayor sea, menor será si el registro se ha movido hacia abajo. ¿Cuál es el truco? Gracias!

¿Fue útil?

Solución

Hacer este tipo de cosas, por ejemplo órdenes de venta con números de línea mantenidos por el usuario, he encontrado que es mejor manejarlo en una matriz en BL o UI. Por lo general, querrán ajustar varios registros, y a veces querrán decir & Quot; olvídalo & Quot ;. Entonces, lo más fácil podría ser esperar hasta que lleguen a & "; OK &"; botón (o su equivalente) y luego escríbalos de nuevo con el pedido actual.

También puede terminar lidiando con eliminaciones, que es otro problema que puede manejar de la misma manera.

Otros consejos

¿Algo como esto lo haría?

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

Lo probé un par de veces y parece funcionar.

Esta es mi opinión sobre esto: mi columna row_index tiene un número con un paso de 10 (por ejemplo: 0, 10, 20, ecc.). Cuando un usuario actualiza una de las filas, necesita saber si está subiendo o bajando. Si tiene que mover la 2da fila a la 4ta (bajando, row_index deseado = 30), establezca row_index en 35; de lo contrario (si sube) configúrelo en 25. Establezca este valor:

UPDATE your_table SET row_index = 35 WHERE your_id = 1234

Ahora tiene el orden correcto, pero los índices de fila están en mal estado. Para solucionar esto, ejecute estas dos consultas:

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

Esto actualizará todas sus filas (o la que seleccione con la instrucción where) y establecerá la columna row_index sin espacios (0, 10, 20, 30, ecc.). Seguramente esta forma agrega carga en las operaciones de escritura, pero creo que es la forma más rápida de obtener el pedido durante las operaciones de lectura. Si elimina una fila, puede volver a ejecutar las consultas de orden de fijación.

Sugeriría, como mínimo, el uso de grandes incrementos (digamos 10000) entre elementos. Entonces solo haciendo un pedido por. Si necesita mover 11000 entre 9000 y 10000, simplemente configúrelo en 9500 y listo.

Esto no elimina el problema de reordenar, pero lo reduce en gran medida. En algún momento, es mejor eliminar todas las filas y luego volver a leerlas en el orden correcto. Hacer actualizaciones como lo estás haciendo es demasiado propenso a errores en mi humilde opinión.

Puede considerar usar un enfoque de tipo de lista vinculada, con una clave para el siguiente, y tal vez el elemento anterior de la lista, entonces solo tiene que actualizar algunos registros, en lugar de todos ellos.

¡Interesante! Bien, entonces no hay una respuesta fácil. Pensé que solo me faltaba algo. Pensé en mantener una matriz externa. Eso suena como la mejor idea.

¿Quizás algo como esto?

$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 
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top