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是指行内块元素,它具有行内元素和块元素两者的特点,可 ...
随机推荐
- bzoj 3531 旅行
动态开点线段树+树链剖分 对于每一种宗教信仰都开一颗线段树 空间: QlogN 即每一次修改都只会改变logN 个点 时间 O(QlogN) naive题 边没有开两倍 QAQ bzoj 35 ...
- 使用bat脚本添加JAVA_HOME和修改PATH
add_jre.bat ::添加环境变量JAVA_HOME @echo off echo 添加java环境变量 set regpath=HKEY_LOCAL_MACHINE\SYSTEM\Curren ...
- MVC授权
public class CommonController : Controller { protected override void OnAuthorization(AuthorizationCo ...
- 随机函数的代码(srand、rand)
#include<stdio.h> int main() int counter; for(counter=0;counter<10;counter++) { srand(count ...
- Bash命令积累
复制本目录下除掉所有的.png文件外的所有其他文件到某个目录下: mv -f !(*.png) ./src/ 除掉所有的.png文件外其余的文件,全部删掉 rm -f !(*.png) 本目录下,不显 ...
- 原生js事件委托
var commontop = document.getElementById("commontop");commontop.onclick = function(ev){ v ...
- Json格式应用
Json格式在用于数据存储方面比xml有着空间上的优势,Json格式又主要分为两种格式:名称/值 对 和数组. 在我的业务环境中需要先把一种空间比较小的格式. 测试如下: 取数据库中的一张表然后生成两 ...
- javascript标识符
标识符,就是指变量.函数.属性的名字,或者函数的参数. 规则 1.第一个字符必须是一个字母.下划线或是美元符号($) 2.其他字符可以是字母.下划线.美元符号或数字 3.不能是关键字和保留字 4.区分 ...
- AngularJS中的Provider们:Service和Factory等的区别
引言 看了很多文章可能还是不太说得出AngularJS中的几个创建供应商(provider)的方法(factory(),service(),provider())到底有啥区别,啥时候该用啥,之前一直傻 ...
- elasticsearch【cat API,系统数据】指令汇总
本博文讲述的ES获取系统数据的API是基于Elasticsearch 2.4.1版本的. 0. overview a. 下面将要介绍的所有的指令,都支持一个查询参数v(verbose),用来显示详细的 ...