2012-07-15 21 views
28

como lo indica el título:ORDEN POR SQLite cadena que contiene el número comenzando con 0

Tengo una consulta de selección, lo que estoy tratando de "ordenar por" un campo que contiene números, la cosa es que estos números son realmente cadenas que comienzan con 0s, por lo que el "orden por" está haciendo esto ...

... 
10 
11 
12 
01 
02 
03 
... 

¿Alguna idea?

EDITAR: si hago esto: "... ORDER BY (campo + 1)" Puedo solucionar esto, porque de alguna manera la cadena se convierte internamente a un entero. ¿Es esta la manera de convertirla "oficialmente" como la atoi de C?

+0

¿Cómo le va ese resultado? ¿Estás seguro de que las cadenas solo tienen ceros a la izquierda o también son los espacios principales involucrados? –

+0

La cadena no tiene espacios iniciales. Estaba tratando de encontrar una manera de ordenar cadenas que contengan números (1,2,3 ..., 10,11,12) sin que se clasifiquen en la forma 1,10,2,3,4,5. Agregué manualmente el 0 principal, lo intenté con espacios también, pero ahora veo que lanzar la columna a INTEGER fue lo más inteligente que se puede hacer en primer lugar. –

+2

Pero ''01'' debería venir antes de '' 10'' cuando están ordenados como cadenas, de ahí mi curiosidad. ¿O estás diciendo que realmente tienes '' 1'' en lugar de ''01'' en la base de datos? –

Respuesta

57

Puede utilizar CASThttp://www.sqlite.org/lang_expr.html#castexpr para emitir la expresión a un entero.

sqlite> CREATE TABLE T (value VARCHAR(2)); 
sqlite> INSERT INTO T (value) VALUES ('10'); 
sqlite> INSERT INTO T (value) VALUES ('11'); 
sqlite> INSERT INTO T (value) VALUES ('12');  
sqlite> INSERT INTO T (value) VALUES ('01'); 
sqlite> INSERT INTO T (value) VALUES ('02'); 
sqlite> INSERT INTO T (value) VALUES ('03'); 
sqlite> SELECT * FROM T ORDER BY CAST(value AS INTEGER); 
01 
02 
03 
10 
11 
12 
sqlite> 

si hago esto: "... ORDER BY (campo + 1)" puedo solucionar esto, porque de alguna manera la cadena interna está siendo convertido a entero. ¿Es la forma de convertirlo "oficialmente" como el atoi de C?

Bueno eso es interesante, aunque yo no sé cuántas DBMS apoyo tal operación, así que no lo recomiendo si acaso alguna vez tiene que utilizar un sistema diferente que no soporta, por no hablar de que están añadiendo una operación extra, lo que puede afectar al rendimiento, aunque también se hace esto ORDER BY (field + 0) Im que va a investigar el rendimiento

tomado de los documentos SQLite3:

una expresión de conversión se utiliza para convertir el valor de a una clase de almacenamiento diferente de forma similar a la c onversion que tiene lugar cuando se aplica una afinidad de columna a un valor. La aplicación de una expresión CAST es diferente de la aplicación de una afinidad de columna, ya que con una expresión CAST la conversión de la clase de almacenamiento se fuerza incluso si es con pérdida e irreversible.

4.0 Operadores
todos los operadores matemáticos (+, -, *, /,%, < <, >>, &, y |) Reparto de los dos operandos a la clase de almacenamiento numérico antes de ser llevado a cabo. El yeso se lleva a cabo incluso si es con pérdida e irreversible. Un operando NULL en un operador matemático produce un resultado NULO. Un operando en un operador matemático que no se ve de ninguna manera numérico y no es NULL se convierte en 0 o 0.0.

que era curiosidades así que corrieron algunos puntos de referencia:

>>> setup = """ 
... import sqlite3 
... import timeit 
... 
... conn = sqlite3.connect(':memory:') 
... c = conn.cursor() 
... c.execute('CREATE TABLE T (value int)') 
... for index in range(4000000, 0, -1): 
...  _ = c.execute('INSERT INTO T (value) VALUES (%i)' % index) 
... conn.commit() 
... """ 
>>> 
>>> cast_conv = "result = c.execute('SELECT * FROM T ORDER BY CAST(value AS INTEGER)')" 
>>> cast_affinity = "result = c.execute('SELECT * FROM T ORDER BY (value + 0)')" 
>>> timeit.Timer(cast_conv, setup).timeit(number = 1) 
18.145697116851807 
>>> timeit.Timer(cast_affinity, setup).timeit(number = 1) 
18.259973049163818 
>>> 

Como podemos ver es un poco más lento, aunque no por mucho, interesante.

+0

+1 gracias por el pequeño experimento –

+1

ど う い て て て て て, no hay problema, actualicé mi respuesta. –

+0

gracias por el punto de referencia! Tal vez los operandos +0 se optimicen antes de ejecutarse, si ese es el caso, +1 o + aleatorio definitivamente llevaría a una consulta más lenta. –

24

Usted podría utilizar CAST:

ORDER BY CAST(columnname AS INTEGER) 
+0

¿Es este el formato correcto? PEDIDO POR REPARTO (columnname AS INTEGER) = '01 ' – sherin

+0

Tenemos un ganador, ¡gracias! – Rob

2

¡En ListView con cursor loader!

String projection= some string column; 
String selection= need to select; 

String sort="CAST ("+ YOUR_COLUMN_NAME + " AS INTEGER)"; 

CursorLoader(getActivity(), Table.CONTENT_URI, projection, selection, selectionArgs, sort); 
0

Gracias a Skinnynerd. con Kotlin, CAST funcionó de la siguiente manera: CAST solucionó los problemas de priorizar 9 sobre 10 o 22 sobre 206.

definen variable global para alterar más tarde en la demanda, y luego enchufarlo en la consulta:

var SortOrder:String?=null 

para alterar el uso orden:

Para descendiente:

SortOrder = "CAST(MyNumber AS INTEGER)" + " DESC" 

(desde más alto a más bajo)

Para ascender:

SortOrder = "CAST(MyNumber AS INTEGER)" + " ASC" 

(de menor a mayor)

Cuestiones relacionadas