Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

Ordenar cadena correctamente

Estas en el tema de Ordenar cadena correctamente en el foro de Mysql en Foros del Web. Hola que tal, tengo un campo "codigo" de tipo varchar que puede contener el siguiente formato XXX-XXX-X ó XXX-XXX-XXX ó XXXX-XXXX-XXX osea que el 1er ...
  #1 (permalink)  
Antiguo 21/07/2013, 21:52
Avatar de totti026  
Fecha de Ingreso: junio-2011
Mensajes: 150
Antigüedad: 12 años, 9 meses
Puntos: 4
Exclamación Ordenar cadena correctamente

Hola que tal, tengo un campo "codigo" de tipo varchar que puede contener el siguiente formato XXX-XXX-X ó XXX-XXX-XXX ó XXXX-XXXX-XXX
osea que
el 1er bloque de 3 a 4 digitos, el 2do bloque de 3 a 4 digitos y el 3er bloque puede ser de 1 a 3 digitos.

El problema que tengo es que mi consulta no me la ordena correctamente.
ejemplo: Tengo estas cadenas y me las ordena asi con la consulta
Código MySQL:
Ver original
  1. SELECT * from codigos ORDER BY codigo ASC
200-201-4
200-201-5
200-201-1
200-201-3
200-201-11
300-301-3
300-302-3
300-301-2
300-302-1
300-301-200
1100-1107-1
1200-1234-1
1400-1401-2
1400-1401-1
1400-1401-100

y lo que pretendo es que me ordene la cadena y ordenados los 3 bloques asi:

200-201-1
200-201-3
200-201-4
200-201-5
200-201-11
300-301-2
300-301-3
300-301-200
300-302-1
300-302-3
1100-1107-1
1200-1234-1
1400-1401-1
1400-1401-2
1400-1401-100
  #2 (permalink)  
Antiguo 22/07/2013, 01:27
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años
Puntos: 574
Respuesta: Ordenar cadena correctamente

Esa cadea es un string luego se va a ordenar según las reglas de ordenació de un string (es decir igual que se ordena un diccionario, teniendo en cuenta que los números van por delante de las letras).

El ejemplo de datos que has puesto se ordena de dos formas según si eliges ASC o DESC

Código MySQL:
Ver original
  1. SELECT * FROM codigos ORDER BY codigo ASC

1100-1107-1
1200-1234-1
1400-1401-1
1400-1401-100
1400-1401-2
200-201-1
200-201-11
200-201-3
200-201-4
200-201-5
300-301-2
300-301-200
300-301-3
300-302-1
300-302-3

Código MySQL:
Ver original
  1. SELECT * FROM codigos ORDER BY codigo DESC


300-302-3
300-302-1
300-301-3
300-301-200
300-301-2
200-201-5
200-201-4
200-201-3
200-201-11
200-201-1
1400-1401-2
1400-1401-100
1400-1401-1
1200-1234-1
1100-1107-1

No hay forma de ordenarlos de otra manera, sin tocar la estructura de datos o sin trabjar con subcadenas.

Estructura:

Usar tres campos de tipo numérico y

Código MySQL:
Ver original
  1. SELECT * FROM codigos ORDER BY codigo1,codigo2,codigo3 ASC

Subcadenas:

En el maual encontramos el siguiente post, donde ya se nos dice que no existe una funció tipo split o explode para separar listas delimitadas por separadores pero dan alguna posible solución

Cita:
Posted by Bob Collins on March 17 2006 8:56pm

MySQL does not include a function to split a delimited string. Although separated data would normally be split into separate fields within a relation data, spliting such can be useful either during initial data load/validation or where such data is held in a text field.

The following formula can be used to extract the Nth item in a delimited list, in this case the 3rd item "ccccc" in the example comma separated list.

select replace(substring(substring_index('aaa,bbbb,ccccc' , ',', 3), length(substring_index('aaa,bbbb,ccccc', ',', 3 - 1)) + 1), ',', '') ITEM3

The above formula does not need the first item to be handled as a special case and returns empty strings correctly when the item count is less than the position requested.
Cita:
Posted by [name withheld] on March 22 2006 8:02pm

This will split an IP address ("a.b.c.d") into 4 respective octets:

SELECT
`ip` ,
SUBSTRING_INDEX( `ip` , '.', 1 ) AS a,
SUBSTRING_INDEX(SUBSTRING_INDEX( `ip` , '.', 2 ),'.',-1) AS b,
SUBSTRING_INDEX(SUBSTRING_INDEX( `ip` , '.', -2 ),'.',1) AS c,
SUBSTRING_INDEX( `ip` , '.', -1 ) AS d
FROM log_table
A todo ello tienes que agregar el convertir los tres valores a numericos

CAST(str AS UNSIGNED)


Código MySQL:
Ver original
  1. SELECT * FROM codigos ORDER BY
  2. CAST(SUBSTRING_INDEX( `codigo` , '-', 1 ) AS UNSIGNED),
  3. CAST(SUBSTRING_INDEX(SUBSTRING_INDEX( `codigo` , '-', 2 ),'-',-1) AS UNSIGNED),
  4. CAST(SUBSTRING_INDEX(SUBSTRING_INDEX( `codigo` , '-', -2 ),'-',1) AS UNSIGNED);

no lo he probado, para estar seguro de con que esta ordenendo haz primero

Código MySQL:
Ver original
  1. CAST(SUBSTRING_INDEX( `codigo` , '-', 1 ) AS UNSIGNED),
  2. CAST(SUBSTRING_INDEX(SUBSTRING_INDEX( `codigo` , '-', 2 ),'-',-1) AS UNSIGNED),
  3. CAST(SUBSTRING_INDEX(SUBSTRING_INDEX( `codigo` , '-', -2 ),'-',1) AS UNSIGNED)
  4. FROM codigos ORDER BY
  5. CAST(SUBSTRING_INDEX( `codigo` , '-', 1 ) AS UNSIGNED),
  6. CAST(SUBSTRING_INDEX(SUBSTRING_INDEX( `codigo` , '-', 2 ),'-',-1) AS UNSIGNED),
  7. CAST(SUBSTRING_INDEX(SUBSTRING_INDEX( `codigo` , '-', -2 ),'-',1) AS UNSIGNED);





es mucho mejor crear los tres campos y trabajar con valores numéricos directamente
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.

Última edición por quimfv; 22/07/2013 a las 01:35
  #3 (permalink)  
Antiguo 22/07/2013, 08:52
Avatar de totti026  
Fecha de Ingreso: junio-2011
Mensajes: 150
Antigüedad: 12 años, 9 meses
Puntos: 4
Respuesta: Ordenar cadena correctamente

quimfv mil gracias, ahora tengo una idea mas clara y bueno ahora a estudiar esa funcion.

Ya lo realice y si me acomoda el 1er y el 2do bloque pero aun falta el tercero..
es cuestion del ORDER BY?

De verdad muchas gracias.
  #4 (permalink)  
Antiguo 22/07/2013, 08:57
Avatar de totti026  
Fecha de Ingreso: junio-2011
Mensajes: 150
Antigüedad: 12 años, 9 meses
Puntos: 4
Respuesta: Ordenar cadena correctamente

Bueno al parecer ya me quedo...
solo modifique el -2 por 3
y el 1 por el -1.
Pero sinceramente aun no se porque se usan números negativos.
Código MySQL:
Ver original
  1. CAST(SUBSTRING_INDEX( `partida_presupuestal` , '-', 1 ) AS UNSIGNED),
  2. CAST(SUBSTRING_INDEX(SUBSTRING_INDEX( `partida_presupuestal` , '-', 2 ),'-',-1) AS UNSIGNED),
  3. CAST(SUBSTRING_INDEX(SUBSTRING_INDEX( `partida_presupuestal` , '-', 3 ),'-',-1) AS UNSIGNED)
  4. FROM comprobacioneselect WHERE id_proyecto='$id_proyecto' ORDER BY
  5. CAST(SUBSTRING_INDEX( `partida_presupuestal` , '-', 1 ) AS UNSIGNED),
  6. CAST(SUBSTRING_INDEX(SUBSTRING_INDEX( `partida_presupuestal` , '-', 2 ),'-',-1) AS UNSIGNED),
  7. CAST(SUBSTRING_INDEX(SUBSTRING_INDEX( `partida_presupuestal` , '-', -2 ),'-',1) AS UNSIGNED);
  #5 (permalink)  
Antiguo 22/07/2013, 09:21
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Ordenar cadena correctamente

Cita:
Pero sinceramente aun no se porque se usan números negativos.
Si lees el manual de referencia, verás que el numero negativo indica desde donde se empieza a leer la cadena, si desde la derecha (negativos) o desde la izquierda (positivos). Es decir, cuál es el punto cero de la cadena.
Otros DBMS usan la misma lógica en ciertas funciones.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Etiquetas: cadena, campo, correctamente, select
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 15:57.