SQL Server的小数数值类型(float 和 decimal)用法

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介:

在SQL Server中,小数数值实际上只有两种数据类型:float 和 decimal。double precision 整体是数据类型,等价于 float(53),real等价于float(24),应该避免在程序中直接使用 double precision 和 real,而是用 float 代替。numeric 和 decimal是同义词。

float是近似数值,存在精度缺失,Decimal是精确数值,不存在精度损失。当数值不允许精度丢失时,使用 decimal数据类型存储。在计算小数的除法时,SQL Server 内部隐式升级数据类型,根据小数数值的数据类型,就近向float(24) 或float(53)转换。

一:近似数值,存在精度损失

1,float 表示近似数值

float数据类型的默认类型是float(53),占用8bytes,实际上,float 只能表示两种类型float(53) 和 float(24),分别占用 4Bytes 和 8Bytes。

float [ (n)

Where n is the number of bits that are used to store the mantissa of the float number in scientific notation and, therefore, dictates the precision and storage size. If n is specified, it must be a value between 1 and 53. The default value of n is 53.

 

n value 

Precision 

Storage size

1-24    

7 digits  

4 bytes 

25-53   

15 digits

8 bytes    

Note:SQL Server treats n as one of two possible values. If 1<=n<=24, n is treated as 24. If 25<=n<=53, n is treated as 53.

2,在SQL Server中,小数常量的默认数据类型是decimal,decimal的优先级比float高。

In Transact-SQL statements, a constant with a decimal point is automatically converted into a numeric data value, using the minimum precision and scale necessary. For example, the constant 12.345 is converted into a numeric value with a precision of 5 and a scale of 3.

示例1,由于在TSQL中,小数数值会自动转换为numeric类型,1.0自动转换为numeric(2, 1),但是在计算除法时,SQL Server 将1.0隐式转换为float(24)。

declare @f_low float(24)
declare @f_high float(53)
select @f_low=cast(1.0 as float(24))/3,@f_high=cast(1.0 as float(53))/3
select 1.0/3 as f,@f_low as f_low, @f_high as f_high

在 WHERE 子句中设置搜索条件(特别是 = 和 <> 运算符),应避免使用 float 列,float 列最好只限于 > 比较或 < 比较。
二,精确数值,不存在精度损失

1,decimal 数据类型需要分别指定小数数值的最大位数(p)和小数位的数量(s),decimal 和 numeric 是等价的。

Numeric data types that have fixed precision and scale.

decimal  [ (p[ ,s] )]

Fixed precision and scale numbers. When maximum precision is used, valid values are from - 10^38 +1 through 10^38 - 1. 

p (precision)             

The maximum total number of decimal digits that will be stored, both to the left and to the right of the decimal point. The precision must be a value from 1 through the maximum precision of 38. The default precision is 18.

s (scale)             

The number of decimal digits that will be stored to the right of the decimal point. This number is substracted from p to determine the maximum number of digits to the left of the decimal point. Scale must be a value from 0 through p. Scale can be specified only if precision is specified. The default scale is 0; therefore, 0 <= s <= p. Maximum storage sizes vary, based on the precision.

Precision

Storage bytes

1 - 9

5

10-19

9

20-28

13

29-38

17

Note:p 和 s 必须遵守规则:0 <= s <= p <= 38

numeric 和 decimal 数据类型的默认最大精度为 38。在 Transact-SQL 中,numeric 的功能等同于 decimal 数据类型。

decimal 数据类型最多可以存储 38 个数字,所有这些数字均可位于小数点后面。decimal 数据类型存储精确的数字表示形式,存储值没有近似值。

定义 decimal 列、变量和参数的两种属性为:

  • p   指定精度或对象能够支持的数字个数。

  • s   指定可以放在小数点右边的小数位数或数字个数。

  • p 和 s 必须遵守规则:0 <= s <= p <= 38。

numeric 和 decimal 数据类型的默认最大精度为 38。在 Transact-SQL 中,numeric 的功能等同于 decimal 数据类型。

2,示例

declare @dec decimal(38,37)
declare @num decimal(38,37)

select @dec=cast(1.0 as decimal(38,37))/3,@num=cast(1.0 as NUMERIC(38,37))
select @dec,@num,1.0/3,cast(1.0 as float(24))/3,1.000000000000/3,cast(1.0 as float(53))/3

3,默认情况下,SQL Server将小数常量作为decimal 数据类型,在计算小数的除法时,就近进行数据类型的升级,转换为float(24)或float(53) 数据类型。

在 Transact-SQL 语句中,小数数值的常量自动转换为 decimal 数据类型,在转换时,使用最小的精度和小数位数。例如,常量 12.345 被转换为 numeric 值,其精度为 5,小数位为 3。

In Transact-SQL statements, a constant with a decimal point is automatically converted into a numeric data value, using the minimum precision and scale necessary. For example, the constant 12.345 is converted into a numeric value with a precision of 5 and a scale of 3.

三,将小数转换成字符串(varchar)

相比cast(float_expression as float(24/53)),使用 str 函数能够有效控制近似数值的小数位数,函数str获取的是近视数值。

STR ( float_expression [ , length [ , decimal ] ] )
  • length是小数的总位数,包含正负符号,小数点,小数点左边和右边数字个数之和;
  • decimal是小数位的数量(小数点右边数字个数),小数位最大为16位,不能超过16,否则,会被截断为16位。如果小数位没有decimal多,那么右边补0。
  • 返回值是varchar类型。

1,对小数常量转换为varchar类型,减少小数位的数量,由2位减少为1位。

SELECT STR(123.45, 6, 1);

2,将decimal 变量转换为varchar类型

declare @d decimal(10,2)
set @d=123.45

SELECT STR(@d, 6, 1);

3,将 float 表达式的值转换为varchar 类型

1.0/3 默认转换为float(24) 类型,因此只有6位小数,小于decimal 参数的8位,右边补两个0。

SELECT STR(1.0/3, 10, 8);

4,在将float和decimal转换为varchar类型时,使用函数str或cast强制转换,返回的数值可能是不相同

复制代码
declare @dt decimal(38,30)
declare @df float(53)

set @dt=50.8863983154297
set @df=50.8863983154297

select @df as df,@dt as dt,
    str(@dt,38,30) as str_dt,str(@df,38,30) as str_df,
    cast(@dt as varchar(100)) as var_dt,cast(@df as varchar(100)) as var_df
复制代码

字段str_dt和str_df的值是不相同的,str函数首先对这两个小数数值取近似值,使用cast强制转换,对于decimal,返回的是精确值,对于float,返回的是近似值。

作者悦光阴
本文版权归作者和博客园所有,欢迎转载,但未经作者同意,必须保留此段声明,且在文章页面醒目位置显示原文连接,否则保留追究法律责任的权利。
分类: SQL Server
标签: 小数, str






本文转自悦光阴博客园博客,原文链接:http://www.cnblogs.com/ljhdo/p/4910699.html,如需转载请自行联系原作者
相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
26天前
|
SQL Java 数据库连接
mybatis使用四:dao接口参数与mapper 接口中SQL的对应和对应方式的总结,MyBatis的parameterType传入参数类型
这篇文章是关于MyBatis中DAO接口参数与Mapper接口中SQL的对应关系,以及如何使用parameterType传入参数类型的详细总结。
30 10
|
2月前
|
SQL XML Java
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
文章介绍了MyBatis中动态SQL的用法,包括if、choose、where、set和trim标签,以及foreach标签的详细使用。通过实际代码示例,展示了如何根据条件动态构建查询、更新和批量插入操作的SQL语句。
mybatis复习03,动态SQL,if,choose,where,set,trim标签及foreach标签的用法
|
28天前
|
SQL 存储 关系型数据库
SQL判断CHAR类型字段不为空的方法与技巧
在SQL查询中,判断一个CHAR类型字段是否不为空是一个常见的需求
|
2月前
|
SQL 存储 安全
SQL Server用法
SQL Server用法
63 1
|
2月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
2月前
|
SQL XML Java
mybatis :sqlmapconfig.xml配置 ++++Mapper XML 文件(sql/insert/delete/update/select)(增删改查)用法
当然,这些仅是MyBatis功能的初步介绍。MyBatis还提供了高级特性,如动态SQL、类型处理器、插件等,可以进一步提供对数据库交互的强大支持和灵活性。希望上述内容对您理解MyBatis的基本操作有所帮助。在实际使用中,您可能还需要根据具体的业务要求调整和优化SQL语句和配置。
44 1
|
4月前
|
SQL 关系型数据库 分布式数据库
PolarDB产品使用问题之相同的SQL语句在不同时间执行EXPLAIN计划显示出不同的索引类型,是什么原因
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
PolarDB产品使用问题之相同的SQL语句在不同时间执行EXPLAIN计划显示出不同的索引类型,是什么原因
|
3月前
|
SQL 数据处理 数据库
SQL中的函数有哪些类型
【8月更文挑战第20天】SQL中的函数有哪些类型
36 1
|
3月前
|
存储 数据库
如何在数据库中存储小数:FLOAT、DECIMAL还是BIGINT?
【8月更文挑战第7天】在数据库中存储小数时,需谨慎选择数据类型:FLOAT、DECIMAL 或 BIGINT。FLOAT 存储空间小,适于非关键性小数如温度;但精度有限,可能产生误差。DECIMAL 能精确表示小数,适合货币金额等需要高度准确性的场景,不过占用空间较大。BIGINT 用于整数,若存储小数需额外转换处理。根据精度需求及应用场景选择合适类型至关重要。
|
3月前
|
SQL 存储 数据库
SQL Server 中的备份类型详解
【8月更文挑战第31天】
65 0