To absolutnie możliwe.
ORDER BY varchar_column::int
Upewnij się, że w swoim varchar masz prawidłowe literały liczb całkowitych kolumna dla każdego wpisu lub otrzymasz wyjątek invalid input syntax for integer: ... . (Pierwsze i końcowe białe znaki są w porządku – zostaną przycięte automatycznie.)
Jeśli tak jest, to dlaczego nie przekonwertować kolumny na integer? najpierw? Mniejszy, szybszy, czystszy, prostszy.
Jak unikać wyjątków?
Aby usunąć znaki niecyfrowe przed rzutowaniem i tym samym uniknąć możliwych wyjątków:
ORDER BY NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '')::int
-
regexp_replace()wyrażenie skutecznie usuwa wszystkie cyfry niebędące cyframi, więc pozostają tylko cyfry lub pusty ciąg. (Patrz poniżej.) -
\Djest skrótem klasy znaków[^[:digit:]], co oznacza wszystkie cyfry niebędące cyframi ([^0-9]).
W starych wersjach Postgresa z przestarzałym ustawieniemstandard_conforming_strings = off, musisz użyć składni łańcucha ucieczki PosixE'\\D'aby zmienić ukośnik odwrotny\. To było domyślne w Postgres 8.3, więc będziesz potrzebować tego w swojej przestarzałej wersji. -
Czwarty parametr
gjest dla „globalnie” , instruując zastąpienie wszystkich wystąpienia, nie tylko pierwsze. -
możesz chcesz zezwolić na wiodący myślnik (
-) dla liczb ujemnych. -
Jeśli ciąg w ogóle nie zawiera cyfr, wynikiem jest pusty ciąg, który nie jest prawidłowy do rzutowania na
integer. Konwertuj puste ciągi naNULLzNULLIF. (Możesz rozważyć0zamiast tego.)
Wynik jest gwarantowany. Ta procedura dotyczy rzutowania na integer zgodnie z żądaniem w treści pytania, nie dla numeric jak wskazuje tytuł.
Jak zrobić to szybko?
Jednym ze sposobów jest indeks wyrażenia.
CREATE INDEX tbl_varchar_col2int_idx ON tbl
(cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer));
Następnie użyj tego samego wyrażenia w ORDER BY klauzula:
ORDER BY
cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer)
Przetestuj za pomocą EXPLAIN ANALYZE czy indeks funkcjonalny faktycznie jest używany.