将varchar字符串排序为数字

时间:2011-12-14 09:55:38

标签: postgresql types casting indexing integer

是否可以在Postgres 8.3中按varchar列投射到integer来订购结果行?

2 个答案:

答案 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;