码迷,mamicode.com
首页 > 其他好文 > 详细

1不等于1?numeric、decimal、float 和 real 数据类型的区别

时间:2016-03-10 20:21:54      阅读:220      评论:0      收藏:0      [点我收藏+]

标签:

大家有没有在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为数值尾数的位数。

现在来看具体的示例。

 1 CREATE TABLE TMAIN(
 2     id INT IDENTITY(1,1) PRIMARY KEY,
 3     val FLOAT
 4 )
 5 GO
 6 
 7 CREATE TABLE TDETAIL(
 8     id INT IDENTITY(1,1) PRIMARY KEY,
 9     pid INT,
10     val FLOAT
11 )
12 GO
13 
14 INSERT INTO TMAIN VALUES(100);
15 INSERT INTO TMAIN VALUES(100);
16 
17 INSERT INTO TDETAIL VALUES(1, 30);
18 INSERT INTO TDETAIL VALUES(1, 35);
19 INSERT INTO TDETAIL VALUES(1, 35);
20 
21 INSERT INTO TDETAIL VALUES(2, 30);
22 INSERT INTO TDETAIL VALUES(2, 30);
23 INSERT INTO TDETAIL VALUES(2, 40);
24 
25 --SELECT * FROM TMAIN;
26 --SELECT * FROM TDETAIL;
27 
28 SELECT TM.id, SUM(TM.val * TD.val) / 10000.0 AS SUMPER
29 FROM TMAIN TM INNER JOIN TDETAIL TD    ON TM.id = TD.pid
30 GROUP BY TM.id
31 
32 SELECT TM.id, SUM(TM.val * TD.val) / 10000.0 AS SUMPER
33 FROM TMAIN TM INNER JOIN TDETAIL TD    ON TM.id = TD.pid
34 GROUP BY TM.id
35 
36 SELECT * 
37 FROM (
38     SELECT TM.id, SUM(TM.val * TD.val / 10000.0) AS SUMPER
39     FROM TMAIN TM INNER JOIN TDETAIL TD    ON TM.id = TD.pid
40     GROUP BY TM.id
41 ) TMS
42 WHERE TMS.SUMPER = 1;
43 
44 SELECT * 
45 FROM (
46     SELECT TM.id, SUM(TM.val * TD.val) / 10000.0 AS SUMPER
47     FROM TMAIN TM INNER JOIN TDETAIL TD    ON TM.id = TD.pid
48     GROUP BY TM.id
49 ) TMS
50 WHERE TMS.SUMPER = 1;
51 
52 DROP TABLE TMAIN;
53 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 数据类型的区别

标签:

原文地址:http://www.cnblogs.com/metro/p/5263152.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!