2012-08-23 23 views
11

tengo cadenas como M1 M3 M4 M14 M30 M40 etc (en realidad cualquier int 2-3 dígitos después de una letra) Cuando hago "ORDER BY nombre" Devuelve:fin de MySQL por cadena con números

M1, M14, M3, M30, M4, M40

Cuando Quiero:

M1, M3, M4, M14, M30, M40 Su tratamiento de todo el asunto como una cadena pero quiero tratarlo como cadena + int

¿Alguna idea?

+0

http://stackoverflow.com/a/153642/1013082 – MetalFrog

+0

Habrá siempre sólo será una letra al comienzo de la cadena? –

+0

http://stackoverflow.com/a/12257917/2008111 – caramba

Respuesta

10

Usted podría utilizar SUBSTR y reparto como sin/con signo dentro de ORDER BY:

SELECT * FROM table_name ORDER BY 
    SUBSTR(col_name FROM 1 FOR 1), 
    CAST(SUBSTR(col_name FROM 2) AS UNSIGNED) 
+0

¡funciona genial gracias! Acabo de cambiar DESDE 1 PARA 2 a DESDE 1 PARA 1 y funciona –

+0

RESPUESTA IMPRESIONANTE ... ¡Hiciste mi día! ¡Gracias! – Monica

+1

@rocky qué hacer si no hay formateado de corrección, posible cadena de me gusta: test1,1test, te2st, test11,2131,10t, t22g –

1

que puede utilizar:

order by name,SUBSTRING(name,1,LENGTH(name)-1) 
+0

Para mí esta es la solución correcta. ¡Gracias! – Stimart

3

Si puede haber múltiples personajes al principio de la cadena, por ejemplo como 'M10', 'MTR10', 'ABCD50', 'JL8', etc..., básicamente tiene que obtener la subcadena del nombre de la primera posición de un número.

Desafortunadamente MySQL no admite ese tipo de operación REGEXP (solo se devuelve un valor booleano, no la coincidencia real).

Puede utilizar esta solución para emularlo:

SELECT name 
FROM  tbl 
ORDER BY CASE WHEN ASCII(SUBSTRING(name,1)) BETWEEN 48 AND 57 THEN 
        CAST(name AS UNSIGNED) 
       WHEN ASCII(SUBSTRING(name,2)) BETWEEN 48 AND 57 THEN 
        SUBSTRING(name,1,1) 
       WHEN ASCII(SUBSTRING(name,3)) BETWEEN 48 AND 57 THEN 
        SUBSTRING(name,1,2) 
       WHEN ASCII(SUBSTRING(name,4)) BETWEEN 48 AND 57 THEN 
        SUBSTRING(name,1,3) 
       WHEN ASCII(SUBSTRING(name,5)) BETWEEN 48 AND 57 THEN 
        SUBSTRING(name,1,4) 
       WHEN ASCII(SUBSTRING(name,6)) BETWEEN 48 AND 57 THEN 
        SUBSTRING(name,1,5) 
       WHEN ASCII(SUBSTRING(name,7)) BETWEEN 48 AND 57 THEN 
        SUBSTRING(name,1,6) 
       WHEN ASCII(SUBSTRING(name,8)) BETWEEN 48 AND 57 THEN 
        SUBSTRING(name,1,7) 
     END, 
     CASE WHEN ASCII(SUBSTRING(name,1)) BETWEEN 48 AND 57 THEN 
        CAST(SUBSTRING(name,1) AS UNSIGNED) 
       WHEN ASCII(SUBSTRING(name,2)) BETWEEN 48 AND 57 THEN 
        CAST(SUBSTRING(name,2) AS UNSIGNED) 
       WHEN ASCII(SUBSTRING(name,3)) BETWEEN 48 AND 57 THEN 
        CAST(SUBSTRING(name,3) AS UNSIGNED) 
       WHEN ASCII(SUBSTRING(name,4)) BETWEEN 48 AND 57 THEN 
        CAST(SUBSTRING(name,4) AS UNSIGNED) 
       WHEN ASCII(SUBSTRING(name,5)) BETWEEN 48 AND 57 THEN 
        CAST(SUBSTRING(name,5) AS UNSIGNED) 
       WHEN ASCII(SUBSTRING(name,6)) BETWEEN 48 AND 57 THEN 
        CAST(SUBSTRING(name,6) AS UNSIGNED) 
       WHEN ASCII(SUBSTRING(name,7)) BETWEEN 48 AND 57 THEN 
        CAST(SUBSTRING(name,7) AS UNSIGNED) 
       WHEN ASCII(SUBSTRING(name,8)) BETWEEN 48 AND 57 THEN 
        CAST(SUBSTRING(name,8) AS UNSIGNED) 
     END 

Esto ordenará por la parte carácter de la cadena en primer lugar, a continuación, el número de pieza extraída de la cadena siempre y cuando no son < = 7 caracteres en el comienzo de la cadena. Si necesita más, puede encadenar WHEN s adicionales a la declaración CASE.

+0

funcionó para mí. Gracias :) –

+0

funciona, pero cómo hacer un pedido si tiene valores numéricos como: 'M10', '40', 'MTR10', 'ABCD50', '8', 'JL8', '55' – sytolk

+0

Su necesidad de agregar ORDER POR nombre * 1, CASO ... antes de que el primer CASO funcione si tiene números limpios entre cadenas mixtas con números. – sytolk

0

Se divide el número y las letras por separado.

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(
SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(col,'1', 1), '2', 1), '3', 1), '4', 1), '5', 1), '6', 1) 
, '7', 1), '8', 1), '9', 1), '0', 1) as new_col 
FROM table group by new_col; 
1

no pude conseguir este trabajo para mi tema que estaba clasificando MLS números, como a continuación:

V12345 V92832 V1000000

El problema se V1000000 no fue objeto de valoración más alta que la descansa a pesar de que es más grande.

Usando esta resuelto mi problema:

ORDER BY CAST(SUBSTR(col_name FROM 2) AS UNSIGNED) DESC 

acaba de quitar la SUBSTR(col_name FROM 1 FOR 1)

0

Intenta quitar el personaje con SUBSTR. A continuación, utilice ABS para obtener el valor absoluto del campo:

SELECT * FROM table ORDER BY ABS(SUBSTR(field,1)); 
Cuestiones relacionadas