在SQL SERVER中执行乘法(基于集合的方法)
假设我有一个如下表: TBL编号 使用基于集合的方法,如何执行乘法,以便输出为:在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,只需定义行数和自联接即
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