È assolutamente possibile.
ORDER BY varchar_column::int
Assicurati di avere valori interi validi nel tuo varchar colonna per ogni voce o ottieni un'eccezione invalid input syntax for integer: ... . (Lo spazio bianco iniziale e finale va bene:verrà tagliato automaticamente.)
Se è così, però, perché non convertire la colonna in integer iniziare con? Più piccolo, più veloce, più pulito, più semplice.
Come evitare le eccezioni?
Per rimuovere i caratteri non numerici prima del cast e quindi evitare possibili eccezioni:
ORDER BY NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '')::int
-
Il
regexp_replace()l'espressione rimuove efficacemente tutte le non cifre, quindi rimangono solo le cifre o una stringa vuota. (Vedi sotto.) -
\Dè un'abbreviazione per la classe di caratteri[^[:digit:]], ovvero tutte le non cifre ([^0-9]).
Nelle vecchie versioni di Postgres con l'impostazione obsoletastandard_conforming_strings = off, devi usare la sintassi della stringa di escape PosixE'\\D'per evitare la barra rovesciata\. Questo era l'impostazione predefinita in Postgres 8.3, quindi ti servirà per la tua versione obsoleta. -
Il 4° parametro
gsta per "globalmente" , indicando di sostituire tutti occorrenze, non solo la prima. -
puoi vuoi consentire un trattino iniziale (
-) per i numeri negativi. -
Se la stringa non ha alcuna cifra, il risultato è una stringa vuota che non è valida per un cast a
integer. Converti stringhe vuote inNULLconNULLIF. (Potresti considerare0invece.)
Il risultato è garantito per essere valido. Questa procedura è per un cast a integer come richiesto nel corpo della domanda, non per numeric come dice il titolo.
Come renderlo veloce?
Un modo è un indice su un'espressione.
CREATE INDEX tbl_varchar_col2int_idx ON tbl
(cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer));
Quindi usa la stessa espressione in ORDER BY clausola:
ORDER BY
cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer)
Prova con EXPLAIN ANALYZE se l'indice funzionale viene effettivamente utilizzato.