2012-08-23 20 views
11

ho stringhe quali M1 M3 M4 M14 M30 M40 ecc (in realtà qualsiasi int 2-3 cifre dopo una lettera) Quando faccio "ORDER BY nome" restituisce:MySQL ordine da stringa con i numeri

M1, M14, M3, M30, M4, M40

Quando voglio:

M1, M3, M4, M14, M30, M40 sua trattare il tutto come una stringa, ma voglio trattarlo come stringa + int

Tutte le idee?

+0

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

+0

Ci sempre essere solo una lettera all'inizio della stringa? –

+0

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

risposta

10

Si potrebbe utilizzare SUBSTR e CAST senza segno/FIRMATO entro ORDER BY:

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

funziona benissimo! Appena cambiato DA 1 PER 2 a DA 1 PER 1 e funziona –

+0

risposta IMPRESSIONANTE ... hai reso la mia giornata! Grazie! – Monica

+1

@rocky cosa fare se non ci sono fix form, possibili stringhe simili: test1,1 test, te2st, test11,2131,10t, t22g –

1

È possibile utilizzare:

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

Per me questa è la soluzione giusta. Grazie! – Stimart

3

Se non ci può essere più caratteri all'inizio della stringa, per esempio come 'M10', 'MTR10', 'ABCD50', 'JL8', etc..., in pratica devi ottenere la sottostringa del nome dalla prima posizione di un numero.

Sfortunatamente MySQL non supporta questo tipo di operazione REGEXP (viene restituito solo un valore booleano, non la corrispondenza effettiva).

È possibile utilizzare questa soluzione per emulare:

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 

Ciò ordinerà dalla parte carattere della stringa, quindi il numero di parte estratta della stringa finché ci sono < = 7 caratteri alla l'inizio della stringa. Se hai bisogno di più, puoi semplicemente aggiungere ulteriori WHEN all'istruzione CASE.

+0

ha funzionato per me. Grazie :) –

+0

ha funzionato ma come ordinare se ha valori numerici come: 'M10', '40', 'MTR10', 'ABCD50', '8', 'JL8', '55' – sytolk

+0

E 'necessario aggiungere ORDINE Per nome * 1, CASE .. prima che il primo CASE funzioni, se ha numeri puliti tra una stringa mista e numeri. – sytolk

0

Ha diviso il numero e le lettere separatamente.

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

non ho potuto ottenere questo a lavorare per il mio problema che è stato l'ordinamento MLS numeri come di seguito:

V12345 V1000000 V92832

Il problema è stato V1000000 non era oggetto di valutazione superiore al resto anche se è più grande.

Usando questo risolto il problema:

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

appena rimosso il SUBSTR(col_name FROM 1 FOR 1)

0

Prova rimuovere il carattere con SUBSTR. Quindi utilizzare ABS per ottenere il valore assoluto dal campo:

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