1不等于1?numeric、decimal、float 和 real 数据类型的区别
大家有没有在SQL中遇见1不等于1(1<>1)的情形!?下面会有一个例子演示这个情形。
先简单介绍一下标题中的四种数值数据类型。
在T-SQL中,numeric和decimal是精确数值数据类型,而float和real是近似数值数据类型。
numeric和decimal是等同的。real等同于float(24).
在定义一个float(n)类型列的时候,如果明确指定了n的值,例如
val float(10)
那么当n的值在1-24之间,系统会将该列(val)标记为real类型;当n的值在25-53之间,系统会将该列标记为float类型。从系统表sys.columns可以得到验证。
如果没有明确指定,n的默认值是53. 补充一下,因为float类型的值是使用科学计数法表示的,所以n表示值的有效位数,MSDN表述n为数值尾数的位数。
现在来看具体的示例。
CREATE TABLE TMAIN(
id INT IDENTITY(1,1) PRIMARY KEY,
val FLOAT
)
GO CREATE TABLE TDETAIL(
id INT IDENTITY(1,1) PRIMARY KEY,
pid INT,
val FLOAT
)
GO INSERT INTO TMAIN VALUES(100);
INSERT INTO TMAIN VALUES(100); INSERT INTO TDETAIL VALUES(1, 30);
INSERT INTO TDETAIL VALUES(1, 35);
INSERT INTO TDETAIL VALUES(1, 35); INSERT INTO TDETAIL VALUES(2, 30);
INSERT INTO TDETAIL VALUES(2, 30);
INSERT INTO TDETAIL VALUES(2, 40); --SELECT * FROM TMAIN;
--SELECT * FROM TDETAIL; SELECT TM.id, SUM(TM.val * TD.val) / 10000.0 AS SUMPER
FROM TMAIN TM INNER JOIN TDETAIL TD ON TM.id = TD.pid
GROUP BY TM.id SELECT TM.id, SUM(TM.val * TD.val) / 10000.0 AS SUMPER
FROM TMAIN TM INNER JOIN TDETAIL TD ON TM.id = TD.pid
GROUP BY TM.id SELECT *
FROM (
SELECT TM.id, SUM(TM.val * TD.val / 10000.0) AS SUMPER
FROM TMAIN TM INNER JOIN TDETAIL TD ON TM.id = TD.pid
GROUP BY TM.id
) TMS
WHERE TMS.SUMPER = 1; SELECT *
FROM (
SELECT TM.id, SUM(TM.val * TD.val) / 10000.0 AS SUMPER
FROM TMAIN TM INNER JOIN TDETAIL TD ON TM.id = TD.pid
GROUP BY TM.id
) TMS
WHERE TMS.SUMPER = 1; DROP TABLE TMAIN;
DROP TABLE TDETAIL;
没执行之前,要不要预测一下结果?
先看一下前二个SELECT语句的执行结果。
第一个SELECT
| id | SUMPER |
| 1 | 1 |
| 2 | 1 |
第二个SELECT
| id | SUMPER |
| 1 | 1 |
| 2 | 1 |
结果是一样的,至少,看上去一样的!
再看一下后两个SELECT语句的执行结果。
第三个SELECT
| id | SUMPER |
| 2 | 1 |
第四个SELECT
| id | SUMPER |
| 1 | 1 |
| 2 | 1 |
后两个SELECT的结果产生了差异:一个是先乘除,后加减;另一个是先加减,后乘除。
因为val列是float类型,是近似数值数据类型,所以很明显,第一个SELECT的结果中有一行数据在计算过程中产生了近似值1. 而WHERE语句中指定的1,默认是int类型,int类型是精确数据类型。所以第三个SELECT语句出现了1<>1的情形。
举例完毕。
如果将val列定义成decimal类型,上面四个SELECT语句的结果是一样的。建议谨慎使用近似数值数据类型,并且在计算和比较值的时候,预见潜在的问题。
1不等于1?numeric、decimal、float 和 real 数据类型的区别的更多相关文章
- SqlServer中decimal(numeric )、float 和 real 数据类型的区别[转]
decimal(numeric ) 同义,用于精确存储数值 float 和 real 不能精确存储数值 decimal 数据类型最 ...
- float与position间的区别
float与position间的区别: 个人理解为:脱离文档流不一定脱离文本流:但脱离文本流,则也脱离文档流.[如有更好的理解还望评论区一起探讨,共同学习进步]一.float 浮动(脱离文档流, ...
- Sql的decimal、float、double类型的区别
三者的区别介绍 float:浮点型,含字节数为4,32bit,数值范围为-3.4E38~3.4E38(7个有效位) double:双精度实型,含字节数为8,64bit数值范围-1.7E308~1.7E ...
- sql decimal & float & celling 介绍
decimal 可以用在指定几个位数比如 123.456, decimal(3,3), 用这类型计算比较准确. 默认情况下,将数字转换为较低精度和小数位数的 decimal 或 numeric 值时, ...
- MySQL中 DECIMAL FLOAT DOUBLE的区别
第一篇文章: MySQL中Decimal类型和Float Double等区别 MySQL中存在float,double等非标准数据类型,也有decimal这种标准数据类型. 其区别在于,float,d ...
- 数据库类型空间效率探索(五)- decimal/float/double/varchar
以下测试为userinfo增加一列,列类型分别为decimal.float.double.varchar.由于innodb不支持optimize,所以每次测试,都会删除表test.userinfo,重 ...
- position:absolute、float、display:inline-block 区别
position: absolute会导致元素脱离文档流,被定位的元素等于在文档中不占据任何位置,在另一个层呈现,可以设置z-index.PS的图层效果就是position: absolute. fl ...
- float和double数据类型的声明,转换和计算
声明时,只要有小数部分float必须加F/f,而double却不用 //float的声明只要有小数部分就要加F,不然会报不能隐式的将double类型转换为float类型. float f1 = 1;/ ...
- 一天搞定CSS: 浮动(float)与inline-block的区别--11
浮动: 使元素脱离文档流,按照指定的方向发生移动,遇到父级的边界或者相邻的浮动元素就会停下来. inline-block: inline-block是指行内块元素,它具有行内元素和块元素两者的特点,可 ...
随机推荐
- delegate和protocol
协议和代理对于一个新手来说确实不讨好理解,也有很多的iOS开发的老手对此是懂非懂的.网上的很多博文只是讲了怎么使用,并没有说的很明白.下面我谈一下我的理解. 1.你要先搞明白,协议和代理为什么会出现, ...
- PHP 与pdf文档 与条码
必要的步骤 1.导入require_once "tcpdf/tcpdf.php"; 工具源码在demo中 2.$pdf = new TCPDF("P", &qu ...
- 缓存,socket乱码等
在服务端默认的编码情况下,JAVA的SOCKET接收需要GBK编码,而C#的接收需要UTF-8编码
- android 观察者模式
1:观察者模式: 1:使用场景:一般使用在自定义控件的事件点击监听上面(或者封装方法进行回调) 2:写观察者模式步骤: (1):声明一个接口 (2):接口里面封装一个抽象方法 (3):需要封装一个 ...
- Sublime Text 添加eclipse快捷键
[ // editor配置 { "keys": ["ctrl+v"], "command": "paste_and_indent& ...
- 微信网页授权snsapi_base、snsapi_userinfo的问题
微信网页授权SCOPE分为snsapi_base.snsapi_userinfo,前者是用户无感知的静默授权只能拿到openid:而后者需要用户确认,能拿到更多的用户信息. 我有一个系统需要进行网页授 ...
- Python爬虫库Scrapy入门1--爬取当当网商品数据
1.关于scrapy库的介绍,可以查看其官方文档:http://scrapy-chs.readthedocs.io/zh_CN/latest/ 2.安装:pip install scrapy 注意这 ...
- RPC与hadoop
rlgdj的这样的话,真正的实现类在Server端,客户端调用方法的时候,只能得到得到从Server端的返回值.看来接口中的抽象方法必须要有返回值啊.ps.右下角的Client端的main()中rpc ...
- consul 安装
1. linux 下consul 安装 首先查看机器信息: uname -a Linux centos-linux.shared 3.10.0-327.el7.x86_64 #1 SMP Thu No ...
- 如何提高Linux操作系统的安全性 转自https://yq.aliyun.com/articles/24251?spm=5176.100239.blogcont24250.7.CfBYE9
摘要: Linux系统不论在功能上.价格上或性能上都有很多优点,但作为开放式操作系统,它不可避免地存在一些安全隐患.关于如何解决这些隐患,为应用提供一个安全的操作平台,本文会告诉你一些最基本.最常用, ...