是否可以在Postgres 8.3中按varchar
列投射到integer
来订购结果行?
答案 0 :(得分:95)
绝对可能。
ORDER BY varchar_column::int
确保varchar
列中包含有效的整数文字,否则会出现异常。 (前导和尾随空格是可以的 - 它会自动修剪。)
如果是这种情况,那么为什么不将列转换为integer
开始?更小,更快,更清洁,更简单。
要在演员表之前删除非数字字符,从而避免可能的例外情况:
ORDER BY NULLIF(regexp_replace(varchar_column, '\D', '', 'g'), '')::int
regexp_replace()
表达式有效删除所有非数字,因此只保留数字或空字符串。 (见下文。)
\D
是字符类[^[:digit:]]
的简写,表示所有非数字([^0-9]
)。
在具有过期设置standard_conforming_strings = off
的旧Postgres版本中,您必须使用Posix转义字符串语法E'\\D'
来转义反斜杠\
。这是Postgres 8.3中的默认值,因此您的过期版本需要这样做。
第四个参数g
适用于"全局" ,指示替换所有次出现,而不仅仅是第一个。
您可能希望允许前导短划线(-
)为负数。
如果字符串根本没有数字,则结果是一个空字符串,对于转换为integer
无效。使用NULLIF
将空字符串转换为NULL
。 (您可能会考虑使用0
。)
结果保证有效。此过程适用于问题正文中的 integer
转换,不适用于标题提及的numeric
。
一种方法是index on an expression。 (链接到手册版本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
测试是否实际使用了功能索引。
答案 1 :(得分:3)
如果你想通过一个可以转换为float的文本列进行排序,那么这样做:
select *
from your_table
order by cast(your_text_column as double precision) desc;