Soh*_*ter 1 sql t-sql sql-server
我使用*符号获得了阶乘值:
declare @given_number int=5;
declare @fact int=1;
while(@given_number > 1)
begin
set @fact = @fact * @given_number;
set @given_number = @given_number - 1;
end
select @fact as 'Factorial is '
Run Code Online (Sandbox Code Playgroud)
但是现在我希望在不使用*符号的情况下获得相同的阶乘值
提供正确的查询,请帮助我吗?
是的,很容易实现CHOOSE:
declare @given_number int=5;
SELECT
@given_number AS given_number,
CHOOSE(@given_number
,1
,2
,6
,24
,120
,720
,5040
,40320
,362880
,3628800
,39916800
,479001600
,6227020800
,87178291200
,1307674368000
,20922789888000
,355687428096000
,6402373705728000
,121645100408832000
,2432902008176640000) AS factorial;
Run Code Online (Sandbox Code Playgroud)
编辑(有趣的部分):
但是你会接受马丁史密斯的挑战,不包括字母S吗?
今天我记得CASE/IIF可能只嵌套10次:)
declare @given_number int=5;
PRINT CONCAT('For ' ,@given_number, ' factorial = ',
IIF(@given_number=1,1
,IIF(@given_number=2,2
,IIF(@given_number=3,6
,IIF(@given_number=4,24
,IIF(@given_number=5,120
,IIF(@given_number=6,720
,IIF(@given_number=7,5040
,IIF(@given_number=8,40320
,IIF(@given_number=9,362880
,IIF(@given_number=10,3628800, -1)))))))))));
Run Code Online (Sandbox Code Playgroud)
EDIT2:
规避方法之一IIF限制是使用原始查询使用动态SQL +交换S用CHAR(83):
declare @t NVARCHAR(MAX) = 'declare @given_number int=5;' + CHAR(83) + 'ELECT given_number = @given_number, factorial = CHOO'+ CHAR(83) +'E(@given_number ,1 ,2 ,6 ,24 ,120 ,720 ,5040 ,40320 ,362880 ,3628800 ,39916800 ,479001600 ,6227020800 ,87178291200 ,1307674368000 ,20922789888000 ,355687428096000 ,6402373705728000 ,121645100408832000 ,2432902008176640000);';
EXEC(@t);
Run Code Online (Sandbox Code Playgroud)
我会使用简单的算术:
set @fact = exp(log(@fact) + log(@given_number));
Run Code Online (Sandbox Code Playgroud)
事实上,你可以在循环中添加日志,但为什么要使用while循环呢?
with f as (
select @given_number as n
union all
select n -1
from f
where n > 1
)
select exp(sum(log(f.n)))
from f;
Run Code Online (Sandbox Code Playgroud)
这有一个很好的特性,它仅限于浮点值的范围,而不是整数。