我有一个问题:
use [Some_Database];
go
select toip 10 IDEVENT,
COUNT(*)
from [AL_PROTOCOL]
group by IDEVENT
order by Quanity desc
go
在输出中,我得到结果
IDEVENT Quanity
664 4,037787E+07
566 2,124254E+07
438 1,248467E+07
294 9926404
564 9777449
436 5784661
310 5709771
428 5161083
432 5154893
434 5150308
然后,我尝试使用(*60 / 1,000,000)
CONVERT (real (100), COUNT(*)*60/1000000, 2) as 'Size, Mb'
列
下一步:
use [Some_Database];
go
select top 10 IDEVENT,
COUNT(*),
CONVERT (real (100), COUNT(*)*60/1000000, 2) as 'Size, Mb'
from [AL_PROTOCOL]
group by IDEVENT
order by Quanity desc
go
在此之后,我收到此错误
8115'将表达式转换为int类型的算术溢出错误 的数字'
Technet解释说,当列中的值过度增加整数类型的最大大小时会发生这种错误。但是,为什么它不能在REAL类型中转换? 此外,这个问题通过替换' * 60 / 1,000,000'在' / 1,000,000 * 60',但我的兴趣不满意。
我做错了什么?感谢
答案 0 :(得分:2)
如果你将一个非常大的数字乘以60,你将得到一个更大的数字,增加了算术溢出的可能性。你之后将它除以1,000,000的事实为时已晚,你已经试图生成一个太大而无法继续的数字。
但是,当你在乘以60之前先将它除以1,000,000,那么你总是会得到一个较小的数字,所以你永远不会得到算术溢出。
此外,对于您的CONVERT
,您在整个结果中执行此操作,并且计算中的所有数字都是INT
类型,因此它将生成INT
之前转换。
COUNT(*)*60/1000000 -- COUNT(*) is an INT, as well as the other numbers
如果您更改CONVERT
\ CAST
的顺序,则应该有效。
DECLARE @number AS INT
SET @number = 123456789
-- this doesn't work
SELECT CAST((@number * 60) AS REAL(100))
-- this does
SELECT CAST(@number AS REAL(100)) * 60
答案 1 :(得分:2)
仔细查看您要求DBMS执行的操作顺序。 CONVERT (real (100), COUNT(*)*60/1000000, 2)
表示:
COUNT(*)
result * 60
result / 1000000
CONVERT (real (100), result, 2)
在第4步之前,该值仍然是整数,因此如果COUNT(*) * 60
高于最大可表示整数,则会出现溢出错误。
由于*
和/
具有相同的优先级,因此您找到的解决方法是CONVERT (real (100), COUNT(*)/1000000*60, 2)
,这意味着:
COUNT(*)
result / 1000000
result * 60
CONVERT (real (100), result, 2)
我们仍在对整数进行数学运算,但现在我们永远不会溢出,因为我们在乘法之前除以。
但你真正想要的是对浮点值进行所有数学运算:
COUNT(*)
CONVERT (real (100), result, 2)
result * 60
result / 1000000
为此,您只需要交换嵌套,以便直接转换COUNT(*)
结果,然后应用数学:CONVERT (real (100), COUNT(*), 2) * 60 / 1000000