asc - order by descendente mysql
¿Cómo almaceno los pedidos? (6)
Tengo una aplicación que tiene tareas y puedes reordenarlas. Ahora estaba luchando por cómo almacenarlos mejor. ¿Debo tener un colomn para el número de orden y volver a calcular todos ellos cada vez que cambio uno? Por favor, dígame una versión que no requiera que actualice todos los números de orden, ya que consume mucho tiempo (desde el punto de vista de las ejecuciones).
Esto es especialmente malo si tengo que poner uno que está en la parte superior del orden y luego lo arrastro hacia abajo.
- Nombre (número de orden)
-
- 1 Ejemplo (1)
- 2 Ejemplo (2)
- 3Ejemplo (3)
- 4 Ejemplo (4)
- 5 Ejemplo (5)
-
- 2 Ejemplo (1) *
- 3Ejemplo (2) *
- 4 Ejemplo (3) *
- 5 Ejemplo (4) *
- 1 Ejemplo (5) *
* tiene que ser cambiado en la base de datos
también algunas tareas pueden eliminarse debido a que se hacen
De tus respuestas surgió una mezcla que dice lo siguiente:
Digamos que tenemos:
- 1 Ejemplo (1)
- 2 Ejemplo (2)
- 3Ejemplo (3)
- 4 Ejemplo (4)
- 5 Ejemplo (5)
Ahora si ordeno algo entre 4 y 5, se vería así:
- 2 Ejemplo (2)
- 3Ejemplo (3)
- 4 Ejemplo (4)
- 1 Ejemplo (4.5)
- 5 Ejemplo (5)
ahora otra vez algo entre 1 y 5
- 3Ejemplo (3)
- 4 Ejemplo (4)
- 1 Ejemplo (4.5)
- 2 Ejemplo (4.75)
- 5 Ejemplo (5)
siempre tomará la mitad de la diferencia entre los números
Espero que eso funcione, por favor corrígeme;)
Lo hacemos con una columna de Secuencia en la base de datos.
Usamos la numeración dispersa (por ejemplo, 10, 20, 30, ...), por lo que podemos "insertar" uno entre los valores existentes. Si las filas adyacentes tienen números consecutivos, volvemos a numerar el número mínimo de filas que podemos.
Probablemente podría usar números decimales: tome el promedio de los números de secuencia para las filas adyacentes a donde está insertando, luego solo debe actualizar la fila "movida"
Yo recomendaría tener una columna de orden en la base de datos. Cuando se reordena un objeto, cambie el valor del pedido en la base de datos entre el objeto que reordenó y los objetos que tienen el mismo valor de orden, de esa manera no tiene que volver a cargar todo el conjunto de filas.
Espero que tenga sentido ... por supuesto, esto depende de tus reglas para reordenar.
Este no es un problema fácil. Si tiene un número bajo de elementos ordenables, simplemente los restablecería a todos en su orden nueva.
De lo contrario, parece que tomaría tanto trabajo o más "probar y establecer" para modificar solo los registros que han cambiado.
Puede delegar este trabajo al lado del cliente. Pídale al cliente que mantenga el orden de clasificación anterior y el orden de clasificación nuevo y determine qué fila [ordenar por orden] debe actualizarse, y luego pasa esas tuplas a la interfaz PHP-mySQL.
Puede mejorar este método de la siguiente manera ( no requiere flotadores):
Si todos los elementos ordenables de una lista se inicializan en un orden de clasificación de acuerdo con su posición en la lista, establezca el orden de clasificación de cada elemento en algo como fila [orden de clasificación] = fila [orden de clasificación * K] donde K es un número> número promedio de veces que espera que la lista se reordene. O (N), N = número de elementos, pero aumenta la capacidad de inserción al menos N * K con al menos K ranuras abiertas entre cada par de elementos salientes.
Entonces, si desea insertar un elemento entre otros dos, es tan simple como cambiar su orden de clasificación para que sea uno que sea> el elemento inferior y <el superior. Si no hay "espacio" entre los elementos, simplemente puede volver a aplicar el algoritmo "spread" (1) presentado en el párrafo anterior. Cuanto mayor sea K, menos se aplicará.
El algoritmo K se aplicaría selectivamente en el script PHP mientras que la elección del nuevo orden sería realizada por el cliente (Javascript, quizás).
Puede mantener los pedidos como literales y usar el tipo léxico:
1. A
2. Z
Agregar una tarea:
1. A
3. L
2. Z
Añadir más:
1. A
4. B
3. L
2. Z
Mover 2 entre 1 y 4:
1. A
2. AL
4. B
3. L
etc.
Actualizas solo un registro a la vez: solo toma una letra promedio entre las primeras que difieren: si pones entre A
y C
, tomas B
, si pones entre ALGJ
y ALILFG
, tomas ALH
.
Letra al lado de conteos existentes como concatenado con el que está junto a Z
I. e. si necesita colocarlo entre ABHDFG
y ABHDFG
F, lo cuenta como ABH
y AB(Z+)
, y escribe AB(letter 35/2)
, que es ABP
.
Si se queda sin longitud de cadena, puede realizar un reordenamiento completo.
Actualizar:
También puede mantener sus datos como una lista vinculada.
Vea el artículo en mi blog sobre cómo hacerlo en MySQL
:
En una palabra:
/* This just returns all records in no particular order */
SELECT *
FROM t_list
id parent
------- --------
1 0
2 3
3 4
4 1
/* This returns all records in intended order */
SELECT @r AS _current,
@r := (
SELECT id
FROM t_list
WHERE parent = _current
)
FROM (
SELECT @r := 0
) vars,
t_list
_current id
------- --------
0 1
1 4
4 3
3 2
Al mover los artículos, deberá actualizar como máximo 4
filas.
Esta parece ser la forma más eficiente de mantener una lista ordenada que se actualiza con frecuencia.
Normalmente agregaré una columna int o smallint llamada algo así como ''Ordinal'' o ''PositionOrdinal'' como sugieres, y con la advertencia exacta que mencionas: la necesidad de actualizar un número potencialmente significativo de registros cada vez que se vuelve a registrar un solo registro ordenado.
El beneficio es que dada una clave para una tarea específica y una nueva posición para esa tarea, el código para mover un elemento es solo dos declaraciones:
UPDATE `Tasks` SET Ordinal= Ordinal+1 WHERE Ordinal>=@NewPosition
UPDATE `Tasks` SET Ordinal= @NewPosition WHERE TaskID= @TaskID
Hay otras sugerencias para una lista doblemente vinculada o un orden léxico. Cualquiera puede ser más rápido, pero a costa de un código mucho más complicado, y el rendimiento solo importará cuando tenga muchos elementos en el mismo grupo.
Si el rendimiento o la complejidad del código es más importante dependerá de su situación. Si tiene millones de registros, la complejidad adicional puede valer la pena. Sin embargo, normalmente prefiero el código más simple porque los usuarios normalmente solo ordenan listas pequeñas a mano . Si no hay tantos elementos en la lista, las actualizaciones adicionales no serán importantes. Esto normalmente puede manejar miles de registros sin ningún impacto notable en el rendimiento.
Una cosa a tener en cuenta con su ejemplo actualizado es que la columna solo se usa para ordenar y no se muestra directamente al usuario. Por lo tanto, al arrastrar un elemento de arriba a abajo, como se muestra, lo único que debe cambiar es ese único registro. No importa que dejes la primera posición vacía. Esto significa que hay un pequeño potencial para desbordar su ordenamiento de enteros con suficiente reordenamiento, pero permítanme decirlo de nuevo: los usuarios normalmente solo ordenan listas pequeñas a mano . Nunca he escuchado que este riesgo realmente cause un problema.