如何在T-SQL查询中不使用*符号查找给定数字的阶乘?

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)

但是现在我希望在不使用*符号的情况下获得相同的阶乘值

提供正确的查询,请帮助我吗?

Luk*_*zda 5

是的,很容易实现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)

DBFiddle演示


编辑(有趣的部分):

但是你会接受马丁史密斯的挑战,不包括字母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)

DBFiddle Demo2

EDIT2:

规避方法之一IIF限制是使用原始查询使用动态SQL +交换SCHAR(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)

DBFiddle演示3

  • 做得好!但是你会接受马丁史密斯的挑战,不包括字母S吗?+1 (4认同)
  • @JohnCappelletti接受挑战.只需用`PRINT`交换`SELECT`,CHOOSE必须转到嵌套的`IIF` :) (4认同)

Gor*_*off 5

我会使用简单的算术:

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)

这有一个很好的特性,它仅限于浮点值的范围,而不是整数。