日期:2014-05-16  浏览次数:21094 次

ORACLE牛人进来看看,这到底是为什么呢?
各位ORACLE牛人,今天遇到一个很邪的问题,以前没有遇到过。
我是在存储过程中遇到的。我把我的问题简化为如下问题。大家有没有遇到过?

有一张表 T1
两个字段 C1 VARCHAR2,C2 NUMBER
T1中的数据由一系统计算得到
如下:
C1 C2
A 100
B 900
C 2589
D 123.6598
E 900
F 120
G 100

执行如下排名语句:
select C1,C2, dense_rank() over (order by C2 DESC) MC FROM T1

C1 C2 MC
C 2589 1
B 900 2
E 900 2
D 123.6598 3
F 120 4
A 100 5
G 100 6

发现,B,E值相同,排名相同。
而A,G值相同,排名却不同
百思不得其解

没办法

select (select C2 from T1 where C1= 'A'),
  (select C2 from T1 where C1= 'G'),
  (select C2 from T1 where C1= 'A') -
  (select C2 from T1 where C1= 'G')
  from dual
--------------------------------
100 100 1E-36


TNND ,计算过程出现精度问题。这个真奇怪,大家遇到吗?
肉眼看不出来呀。



------解决方案--------------------
在SQLPLUS下这样

sql>set numwidth 30

然后执行这个语句看一下,肯定值不一样
select (select C2 from T1 where C1= 'A'),
(select C2 from T1 where C1= 'G'),
(select C2 from T1 where C1= 'A') -
(select C2 from T1 where C1= 'G')
from dual
------解决方案--------------------
T1中的数据由一系统计算得到???
说明A 100 5
G 100 6

根本就不是100,你的计算也证明了


和在SQLPLUS下这样

sql>set numwidth 30

没有任何关系,你设成set numwidth 2结果也是一样的,sqlplus客户端命令只会改变显示效果,不会改变SQL的执行结果
------解决方案--------------------
C2 类型是什么?是不是你的类型指定了精度度?
------解决方案--------------------
SQL code
SQL> with t1 as (
  2             select 'A' c1, 100 c2 from dual union all
  3             select 'B' c1,    900  c2 from dual union all
  4             select 'C' c1,    2589  c2 from dual union all
  5             select 'D' c1,    123.6598  c2 from dual union all
  6             select 'E' c1,    900  c2 from dual union all
  7             select 'F' c1,    120  c2 from dual union all
  8             select 'G' c1,    100  c2 from dual
  9            )
 10   select C1,C2, dense_rank() over (order by C2 DESC) MC FROM T1
 11  /
 
C1         C2         MC
-- ---------- ----------
C        2589          1
E         900          2
B         900          2
D    123.6598          3
F         120          4
A         100          5
G         100          5
 
7 rows selected

------解决方案--------------------
可见,你的计算并非是2个值都是100,可能有小数位上的误差

------解决方案--------------------
听说这是oracle的一个bug
------解决方案--------------------
没有发现类似的情况


create table t1(c1 varchar2(10),c2 number);
insert into t1 select 'A',100 from dual;
insert into t1 select 'B',900 from dual;
insert into t1 select 'C',2589 from dual;
insert into t1 select 'D',123.6598 from dual;
insert into t1 select 'E',900 from dual;
insert into t1 select 'F',120 from dual;
insert into t1 select 'G',100 from dual;

select c1,c2,dense_rank()over(order by c2 desc) from t1

C 2589 1
E 900 2
B 900 2
D 123.6598 3
F 120 4
A 100 5
G 100 5