SQL para ordenar por número: 1, 2, 3, 4, etc.en lugar de 1, 10, 11, 12

86

Estoy intentando ordenar por una columna numérica en mi base de datos que tiene valores 1-999

Cuando uso

ORDER_BY registration_no ASC

Yo obtengo….

1
101
102
103
104
105
106
107
108
109
11
110
Etc…

Así que parece estar ordenando por el primer dígito en oposición al número.

¿Alguien sabe qué SQL usar si quiero ordenar esto por valor? Entonces, 1,2,3,4,5,6etc.

Konnor262
fuente
11
Su columna es de tipo varchar por lo que se enfrenta a este comportamiento.
Meherzad
¿Cuál es el tipo de datos de la columna registration_no?
Praveen Prasannan
9
Utilizar order by registration_no + 0 asc para resolver su problema.
Meherzad
10
Usted debe Nunca almacenar números en una columna de caracteres. Su problema es el resultado directo de ese error.
a_horse_with_no_name
Mi columna es Varchar y los datos que almaceno son Clase 10 / Clase 9 / Clase 8. Ahora la clase 10 viene antes que la clase 8. ¿Cómo soluciono esto sin tener que hacer una columna display_order?
Vishnoo Rath

Respuestas:

139

Una forma de ordenar por enteros positivos, cuando se almacenan como varchar, es ordenar primero por la longitud y luego por el valor:

order by len(registration_no), registration_no

Esto es particularmente útil cuando la columna puede contener valores no numéricos.

Nota: en algunas bases de datos, la función para obtener la longitud de una cadena podría llamarse en length()lugar de len().

Gordon Linoff
fuente
1
Esto no funcionará en todos los casos. En la parte superior de la cabeza, los casos que no funcionarán son mezclas de números enteros con; números negativos, números con ceros a la izquierda, números con fracciones y palabras y números combinados.
WonderWorker
10
@ Knickerless-Noggins. . . Lee la primera oración de la respuesta. Creo que está bastante claro.
Gordon Linoff
@GordonLinoff está ordenando por la misma columna dos veces, ¿no consume mucho CPU y memoria?
loneStar
@Achyuth. . . El número de teclas en un order bytiene poco efecto sobre el rendimiento.
Gordon Linoff
1
Para Oracle SQL, utilice en length()lugar delen()
Stevoisiak
61
ORDER_BY cast(registration_no as unsigned) ASC

convierte explícitamente el valor en un número. Otra posibilidad de lograr lo mismo sería

ORDER_BY registration_no + 0 ASC

lo que forzará una conversación implícita.

En realidad, debería comprobar la definición de la tabla y cambiarla. Puede cambiar el tipo de datos a Me intgusta esto

ALTER TABLE your_table MODIFY COLUMN registration_no int;
juergen d
fuente
13

Si está utilizando SQL Server:

ORDER_BY cast(registration_no as int) ASC
IPOSTEDONCE
fuente
3
ORDER_BY cast(registration_no as unsigned) ASC

da el resultado deseado con advertencias.

Por lo tanto, es mejor ir por

ORDER_BY registration_no + 0 ASC

para un resultado limpio sin advertencias SQL.

priyanka
fuente
2

Supongo que su tipo de columna es STRING (CHAR, VARCHAR, etc.) y el procedimiento de clasificación lo clasifica como una cadena. Lo que debe hacer es convertir el valor en valor numérico. Cómo hacerlo dependerá del sistema SQL que utilice.


fuente
1

A veces simplemente no tiene la opción de almacenar números mezclados con texto. En una de nuestras aplicaciones, el host del sitio web que utilizamos para nuestro sitio de comercio electrónico crea filtros dinámicamente a partir de listas. No hay ninguna opción para ordenar por ningún campo que no sea el texto mostrado. Cuando queríamos que los filtros se construyeran a partir de una lista que dijera cosas como 2 "a 8" 9 "a 12" 13 "a 15", etc., lo necesitábamos para ordenar 2-9-13, no 13-2-9 como ocurrirá cuando leer los valores numéricos. Así que utilicé la función de replicación de SQL Server junto con la longitud del número más largo para rellenar los números más cortos con un espacio inicial. Ahora 20 se ordena después de 3, y así sucesivamente.

Estaba trabajando con una vista que me dio las longitudes, anchos, etc. mínimos y máximos para el tipo de elemento y la clase, y aquí hay un ejemplo de cómo hice el texto. (LB n Low y LB n High son los extremos inferior y superior de los 5 soportes de longitud).

REPLICATE(' ', LEN(LB5Low) - LEN(LB1High)) + CONVERT(NVARCHAR(4), LB1High) + '" and Under' AS L1Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB2Low)) + CONVERT(NVARCHAR(4), LB2Low) + '" to ' + CONVERT(NVARCHAR(4), LB2High) + '"' AS L2Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB3Low)) + CONVERT(NVARCHAR(4), LB3Low) + '" to ' + CONVERT(NVARCHAR(4), LB3High) + '"' AS L3Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB4Low)) + CONVERT(NVARCHAR(4), LB4Low) + '" to ' + CONVERT(NVARCHAR(4), LB4High) + '"' AS L4Text,
CONVERT(NVARCHAR(4), LB5Low) + '" and Over' AS L5Text
Joey Morgan
fuente
1

Prefiero hacer un "PAD" a los datos. MySql lo llama LPAD, pero puede trabajar para hacer lo mismo en SQL Server.

ORDER BY  REPLACE(STR(ColName, 3), SPACE(1), '0') 

Esta fórmula proporcionará ceros iniciales basados ​​en la longitud de la columna de 3. Esta funcionalidad es muy útil en otras situaciones fuera de ORDER BY, por eso quería proporcionar esta opción.

Resultados: 1 se convierte en 001 y 10 se convierte en 010, mientras que 100 permanece igual.

SQLCodingIsFunnn
fuente
0

Este problema se debe simplemente a que ha declarado la columna en el tipo de datos CHAR, VARCHAR o TEXT. Simplemente cambie el tipo de datos a INT, BIGINT, etc. Esto resolverá el problema de su pedido personalizado.

Dev Rathi
fuente