Это абсолютно возможно.
ORDER BY varchar_column::int
Убедитесь, что в столбце varchar
указаны допустимые целочисленные литералы, иначе вы получите исключение. (Начальные и конечные пробелы в порядке - они будут обрезаны автоматически.)
Если это так, то почему бы не преобразовать столбец в integer
для начала? Меньше, быстрее, чище, проще.
Как избежать исключений?
Чтобы удалить нецифровые символы перед приведением и, таким образом, избежать возможных исключений:
ORDER BY NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '')::int
Выражение regexp_replace()
эффективно удаляет все нецифровые символы, поэтому остаются только цифры или пустая строка. (См. Ниже.)
\D
- сокращение для класса символов [^[:digit:]]
, означающее все нецифровые символы ([^0-9]
).
В старых версиях Postgres с устаревшей настройкой standard_conforming_strings = off
необходимо использовать синтаксис escape-строки Posix E'\\D'
, чтобы избежать обратной косой черты \
. Это было по умолчанию в Postgres 8.3, поэтому вам понадобится это для вашей устаревшей версии.
4-й параметр g
предназначен для «глобально» , инструктируя замену всех вхождений, а не только первого.
Вы можете хотите разрешить начальную черту (-
) для отрицательных чисел.
Если строка не имеет цифр вообще, результатом является пустая строка, которая недопустима для приведения к integer
. Преобразуйте пустые строки в NULL
с помощью NULLIF
. (Вы можете рассмотреть 0
вместо этого.)
Результат гарантированно будет действительным. Эта процедура предназначена для приведения к integer
, как указано в основной части вопроса, не для numeric
, как упоминается в заголовке.
Как сделать это быстро?
Одним из способов является индекс для выражения . (Ссылка на ручную версию 8.3.)
CREATE INDEX tbl_varchar_col2int_idx ON tbl
(cast(NULLIF(regexp_replace(varchar_column, E'\\D', '', 'g'), '') AS integer));
Затем используйте то же выражение в предложении ORDER BY
:
ORDER BY
cast(NULLIF(regexp_replace(varchar_column, E'\\D', '', 'g'), '') AS integer)
Проверьте с помощью EXPLAIN ANALYZE
, действительно ли используется функциональный индекс.