在数据库的实际使用中,我们经常会把数字内容存储在varchar类型的字段里,比如商品编号、楼层号、序号这类数据。如果直接对这类字段执行order by排序,数据库会按照字符串的规则逐位比较,导致排序结果不符合数值排序的预期,比如会出现1、10、11、2、20这样的顺序。要解决这个问题,就需要用CAST或者CONVERT函数把varchar字段转换为数值类型后再排序。

CAST函数的基本语法
CAST是SQL标准中定义的类型转换函数,通用性比较强,大部分关系型数据库都支持。它的基本语法格式如下:
CAST(字段名 AS 目标数据类型)
常用的目标数值类型包括INT、DECIMAL、BIGINT等,具体选择哪种类型要根据字段实际存储的内容决定。如果字段存储的是整数,用INT就可以;如果包含小数,就需要用DECIMAL。
CONVERT函数的基本语法
CONVERT是部分数据库(比如MySQL、SQL Server)支持的类型转换函数,功能和CAST类似,但是语法格式略有不同。基本语法如下:
-- MySQL语法 CONVERT(字段名, 目标数据类型) -- SQL Server语法 CONVERT(目标数据类型, 字段名)
需要注意不同数据库的CONVERT语法差异,避免写错导致执行报错。
具体实现示例
MySQL场景下的实现
假设我们有一张product表,其中product_no是varchar类型,存储商品的编号数字,现在需要按照编号升序排序,正确的语句如下:
-- 使用CAST实现 SELECT * FROM product ORDER BY CAST(product_no AS UNSIGNED); -- 使用CONVERT实现 SELECT * FROM product ORDER BY CONVERT(product_no, UNSIGNED);
这里UNSIGNED是无符号整数的类型,适合存储正数的编号字段。
SQL Server场景下的实现
同样的需求在SQL Server中,实现语句如下:
-- 使用CAST实现 SELECT * FROM product ORDER BY CAST(product_no AS INT); -- 使用CONVERT实现 SELECT * FROM product ORDER BY CONVERT(INT, product_no);
注意事项
- 如果varchar字段中包含非数字的字符,转换的时候会报错,所以使用前要确认字段内容都是可转换为数值的内容,或者提前用函数过滤掉非数字字符。
- 转换后的排序是数值排序,会按照数字大小排列,符合我们常规的理解。
- 如果字段存储的是小数,转换的时候要对应选择DECIMAL类型,比如
CAST(price AS DECIMAL(10,2)),其中10是总位数,2是小数位数。
两种函数的选择建议
如果需要写跨数据库的通用SQL,优先选择CAST函数,因为它是SQL标准函数,兼容性更好。如果只在特定的数据库中使用,两种函数都可以,根据团队的编码习惯选择即可。如果转换的时候出现报错,先检查字段内容是否包含无法转换的字符,再检查目标数据类型是否匹配字段的实际内容。