Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在SQL SERVER中执行乘法(基于集合的方法)_Sql_Sql Server_Sql Server 2005_Tsql - Fatal编程技术网

在SQL SERVER中执行乘法(基于集合的方法)

在SQL SERVER中执行乘法(基于集合的方法),sql,sql-server,sql-server-2005,tsql,Sql,Sql Server,Sql Server 2005,Tsql,假设我有一个如下表: TBL编号 使用基于集合的方法,如何执行乘法,以便输出为: Output 360 注意:没有硬性规定只有四个数字,但我更喜欢使用CTE和/或相关子查询 declare @result int set @result = 1 select @result = @result * [number] from tblNumber print @result (注意,这假设一个int列并且没有溢出)Michael的结果是有效的 您可以使用递归CTE,只需定义行数和自联接即

假设我有一个如下表:

TBL编号 使用基于集合的方法,如何执行乘法,以便输出为:

Output
360 
注意:没有硬性规定只有四个数字,但我更喜欢使用CTE和/或相关子查询

declare @result int
set @result = 1

select @result = @result * [number]
from tblNumber

print @result

(注意,这假设一个int列并且没有溢出)

Michael的结果是有效的


您可以使用递归CTE,只需定义行数和自联接即可。但是为什么要麻烦呢,它不会那么有效,因为您无论如何都需要进行表或索引扫描。

您可以使用对数/指数,利用数学事实:

log(a*b*c...*n)=log(a)+log(b)+log(c)...+log(n)
因此,您可以使用
sum
函数将一列的所有对数相加,然后取该和的指数,该指数给出该列的合计乘法:

create table #tbl (val int)
insert into #tbl (val) values(1)
insert into #tbl (val) values(2)
insert into #tbl (val) values(3)
insert into #tbl (val) values(4)

select exp(sum(log(val))) from #tbl

drop table #tbl

如果我没记错的话,有一个边缘案例需要处理。。。日志(0)是一个错误。

如果不声明@result,我们不能使用其他方法吗?好像我不想接受任何变量的帮助。我基本上是在尝试使用递归CTE获得解决方案。但到目前为止,运气不好。我必须使用CTE/相关子查询等+1来实现平滑。太糟糕了,你必须包装它来检查零,并且必须考虑舍入/强制转换/溢出问题,并且在使用浮点时可能会引入精度错误。很好的解决方案。我印象深刻。。这就是我正在寻找的方法。注意,对于大型集合,这种方法会引入舍入误差。您可以尝试使用clr解决方案。它速度慢但准确。我在这里比较了2个:试着找出mssql中是否有类似的用户定义聚合。这是我对postgresql感到自豪的东西,它有许多其他rdbms中缺少的功能:-)嗯。。在mssql中,用户可以创建用户定义的聚合,但会强制用户使用.net。我不知道用户是否可以在mssql中创建用户定义的聚合,这样更有效
create table #tbl (val int)
insert into #tbl (val) values(1)
insert into #tbl (val) values(2)
insert into #tbl (val) values(3)
insert into #tbl (val) values(4)

select exp(sum(log(val))) from #tbl

drop table #tbl