大家有没有在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 数据类型的区别的更多相关文章

  1. SqlServer中decimal(numeric )、float 和 real 数据类型的区别[转]

    decimal(numeric )             同义,用于精确存储数值 float 和 real                      不能精确存储数值   decimal 数据类型最 ...

  2. float与position间的区别

    float与position间的区别:    个人理解为:脱离文档流不一定脱离文本流:但脱离文本流,则也脱离文档流.[如有更好的理解还望评论区一起探讨,共同学习进步]一.float 浮动(脱离文档流, ...

  3. Sql的decimal、float、double类型的区别

    三者的区别介绍 float:浮点型,含字节数为4,32bit,数值范围为-3.4E38~3.4E38(7个有效位) double:双精度实型,含字节数为8,64bit数值范围-1.7E308~1.7E ...

  4. sql decimal & float & celling 介绍

    decimal 可以用在指定几个位数比如 123.456, decimal(3,3), 用这类型计算比较准确. 默认情况下,将数字转换为较低精度和小数位数的 decimal 或 numeric 值时, ...

  5. MySQL中 DECIMAL FLOAT DOUBLE的区别

    第一篇文章: MySQL中Decimal类型和Float Double等区别 MySQL中存在float,double等非标准数据类型,也有decimal这种标准数据类型. 其区别在于,float,d ...

  6. 数据库类型空间效率探索(五)- decimal/float/double/varchar

    以下测试为userinfo增加一列,列类型分别为decimal.float.double.varchar.由于innodb不支持optimize,所以每次测试,都会删除表test.userinfo,重 ...

  7. position:absolute、float、display:inline-block 区别

    position: absolute会导致元素脱离文档流,被定位的元素等于在文档中不占据任何位置,在另一个层呈现,可以设置z-index.PS的图层效果就是position: absolute. fl ...

  8. float和double数据类型的声明,转换和计算

    声明时,只要有小数部分float必须加F/f,而double却不用 //float的声明只要有小数部分就要加F,不然会报不能隐式的将double类型转换为float类型. float f1 = 1;/ ...

  9. 一天搞定CSS: 浮动(float)与inline-block的区别--11

    浮动: 使元素脱离文档流,按照指定的方向发生移动,遇到父级的边界或者相邻的浮动元素就会停下来. inline-block: inline-block是指行内块元素,它具有行内元素和块元素两者的特点,可 ...

随机推荐

  1. 笔记 进程(processes)

    进程:a program in execution(执行中的程序) 进程包括通过程序计数器(program counter)的值和处理器寄存器(processor's registers)的内容来表示 ...

  2. dependency of static library

    一直以来都有一个误区,认为静态库就一定是不含任何依赖的,动态库是含的.这个印象是因为在我们程序中,包含静态库的地方,往往Build好之后直接就可以用,而含DLL的地方,则需要在build好之后的EXE ...

  3. browser shell

    我一直坚信,做项目需要通过文档来总结.一来可以梳理自己的项目和思路,二来可以备忘,三则可以为有同样需求的朋友提供一些参考.如果一直不进行总结,真的很可能是写了多年的代码,却只有一年的经验.当学习一项新 ...

  4. acm之poj题库1001方法

    题目所言是银行等不能用四舍五入等影响精度的方法来计算的情况,是为提出背景.因此需要特殊的编写.这里使用了好几种方法才找到一个合适的方法.因为C++或者C缺乏类库,又跟底层关联太大,缺乏常用的类库,在写 ...

  5. 基于服务(Web Service)的文件管理Winform客户端实现(二)

    上一篇主要介绍文件管理服务有哪些方法,实现了哪些功能. 基于服务(Web Service)的文件管理Winform客户端实现(一) 本篇将根据文件服务服务实现Winform客户端设计.开发. 3.   ...

  6. 承接Holograms外包 Holograms内容定制 Holograms场景外包开发

    HoloLens仿真器与文档现已向开发者们开放 如何为Microsoft HoloLens全息眼镜开发应用? 每款运行Windows 10的设备都使用了相同统一的Windows内核.所以你学习了所有有 ...

  7. JMeter压测Rest请求

    下载及安装 官网下载JMeter3.0: 找到bin目录下的jmeter.bat启动: 压测Rest请求 1.添加线程组 路径:右键“测试计划”->添加“Threads(Users)”-> ...

  8. 【学】AngularJS日记(3)- $apply(), run()方法

    $scope.$apply()方法可以强制$apply()里运行的函数所改变的model里的数据直接反应到view里,因为在angular的环境中,有时会用到原生js或者jquery的时候,这些行为有 ...

  9. 高阶c++

    模板就是宏.模板能不能再往一步? http://perilla.codeplex.com/ enhanced c++ template grammar: rule 1: c++ identifier ...

  10. 一. DotNet MVC4.0+EasyUI Web简单框架-前言

    之所以说它简单,是因为仅仅用了大家最熟悉的三层架构,简单明了 1.先新建一个MVC4.0 Web项目 2.添加EasyUI的引用,放到Script底下 http://files.cnblogs.com ...