それは絶対に可能です。
ORDER BY varchar_column::int
varcharに有効な整数リテラルがあることを確認してください 各エントリの列、または例外invalid input syntax for integer: ... 。 (先頭と末尾の空白は問題ありません。自動的にトリミングされます。)
その場合は、列をintegerに変換してみませんか。 そもそも?より小さく、より速く、よりクリーンで、よりシンプルに。
例外を回避する方法は?
キャストの前に数字以外の文字を削除して、発生する可能性のある例外を回避するには:
ORDER BY NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '')::int
-
regexp_replace()式は数字以外のすべてを効果的に削除するため、数字のみが残るか、空の文字列になります。 (以下を参照してください。) -
\D文字クラス[^[:digit:]]の省略形です 、すべての非数字を意味します([^0-9])。
古い設定の古いPostgresバージョンではstandard_conforming_strings = off、Posixエスケープ文字列構文E'\\D'を使用する必要があります バックスラッシュをエスケープするには\。これはPostgres8.3のデフォルトであったため、古いバージョンではこれが必要になります。 -
4番目のパラメータ
g「グローバルに」用です 、すべてを置き換えるように指示する 最初だけでなく、発生。 -
あなたはかもしれません 先頭のダッシュを許可する(
-)負の数の場合。 -
文字列に数字がまったくない場合、結果は空の文字列になり、
integerへのキャストには無効になります。 。空の文字列をNULLに変換しますNULLIFを使用 。 (0を検討するかもしれません 代わりに。)
結果は有効であることが保証されています。この手順は、integerへのキャスト用です 質問の本文で要求されているように、numericではありません タイトルにあるように。
高速化するには?
1つの方法は、式のインデックスです。
CREATE INDEX tbl_varchar_col2int_idx ON tbl
(cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer));
次に、ORDER BYで同じ式を使用します 条項:
ORDER BY
cast(NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '') AS integer)
EXPLAIN ANALYZEでテストする 機能インデックスが実際に使用されるかどうか。