我是SQL函数的初学者。 在SQL Server中创建factorial函数的最佳方法是什么?Say 10!
答案 0 :(得分:17)
非递归方式
;With Nums As
(
select ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS RN
FROM sys.objects
)
SELECT POWER(10.0, SUM(LOG10(RN)))
FROM Nums
WHERE RN <= 10
以递归的方式
declare @target int
set @target=10;
WITH N AS
(SELECT 1 AS i,
1 AS f
UNION ALL
SELECT i+1,
f*(i+1)
FROM N
WHERE i < @target
)
SELECT f FROM N
WHERE i=@target
答案 1 :(得分:11)
这是一个递归解决方案:
CREATE FUNCTION dbo.Factorial ( @iNumber int )
RETURNS INT
AS
BEGIN
DECLARE @i int
IF @iNumber <= 1
SET @i = 1
ELSE
SET @i = @iNumber * dbo.Factorial( @iNumber - 1 )
RETURN (@i)
END
答案 2 :(得分:3)
- 迭代方法。 - 为什么选择迭代?它更简单,更快捷。 - 对于@N从0到20,这给出了精确的结果。 - 21会溢出。
DECLARE @N Bigint = 20
DECLARE @F Bigint = 1
WHILE @N > 0 BEGIN
SET @F = @f*@n
SET @N = @N-1
END
SELECT @F AS FACTORIAL
- 将数据类型更改为float,您可以获得最多170的阶乘。 - 171将导致溢出。 - 注意结果只能在有限数量的位置上准确。
DECLARE @N FLOAT = 170
DECLARE @F FLOAT = 1
WHILE @N > 0 BEGIN
SET @F = @f*@n
SET @N = @N-1
END
SELECT @F AS FACTORIAL
- 本
答案 3 :(得分:2)
试试这个
WITH MYCTE AS(
SELECT VAL=1,NUM =6
UNION ALL
SELECT VAL=VAL*NUM,NUM = (NUM -1)
FROM MYCTE
WHERE NUM > 1
)
SELECT VAL FROM MYCTE
答案 4 :(得分:1)
...用于基于Set的方法:
DECLARE @n int=11, @f bigint=1;
WITH
t(n,f) AS (SELECT TOP(@n)
ROW_NUMBER() OVER (ORDER BY (SELECT NULL))+1,
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) *
(ROW_NUMBER() OVER (ORDER BY (SELECT NULL))+1)
FROM sys.all_columns
UNION SELECT 1, f=CASE WHEN @n=0 THEN 0 ELSE 1 END)
SELECT @f=@f*f
FROM t
WHERE n%2=@n%2 OR f=0;
SELECT @f AS FACTORIAL;
答案 5 :(得分:0)
我知道我在这里有点晚了,但值得注意的是,Martin发布的递归方式不适用于0.
这将(原谅我,我在发布代码时遇到了问题):
declare @target int=3;
WITH N AS
(SELECT 1 AS i,
1 AS f
UNION ALL
SELECT i+1,
f*(i+1)
FROM N
WHERE i < @target),
N0 AS
(SELECT f FROM N WHERE i=@target UNION SELECT 0)
SELECT MAX(f) FROM N0
顺便说一下,版本更快:
declare @target int=5;
WITH N AS
(SELECT 1 AS i,
1 AS f
UNION ALL
SELECT i+1,
f*(i+1)
FROM N
WHERE i < @target),
N0 AS
(SELECT f FROM N WHERE i=@target UNION SELECT f=CASE WHEN @target=0 THEN 0 END)
SELECT f FROM N0
WHERE f>=0
这要快得多,因为我失去了MAX()函数,就像前1一样,会导致DISTINCT排序。
答案 6 :(得分:0)
以下是calculate factorial value of an integer in SQL Server
的另一种方法 create function sqlFactorial (@int int)
returns int
begin
declare @factorial bigint = 1
select @factorial = @factorial * i from dbo.NumbersTable(1,@int,1)
return @factorial
end
您需要为此解决方案使用SQL numbers table。 Select语句为FROM部分中的每一行更新声明的整数变量,并将其与有序整数值相乘
答案 7 :(得分:0)
如果您对近似值没问题,请使用Stirling's Approximation。
create table #temp (value int)
insert into #temp values (5),(6),(7),(8)
select
value,
sqrt(2*3.14*value)*power((value/2.718),value) --stirling's approx.
from #temp
请注意,如果需要,您必须为0!做个案例。
答案 8 :(得分:0)
您询问在SQL Server中为阶乘创建函数的最佳方法。与往常一样,这取决于上下文。但是,如果您从性能意义上的通用意义上真正地表示它,那么最好的选择无疑是将其实现为CLR用户定义的函数。
您当然可以用自己喜欢的任何语言来实现该功能。而且long / bigint并不能真正将其用于阶乘函数(bigint只能容纳20!,21!是算术溢出)。
答案 9 :(得分:0)
/ *打印阶乘序列* /
WITH MYCTE AS(
SELECT VAL=1,NUM =1
UNION ALL
SELECT VAL=VAL*(NUM+1),NUM = (NUM +1)
FROM MYCTE
WHERE NUM < 11
)
SELECT VAL FROM MYCTE
OPTION (MAXRECURSION 0);
答案 10 :(得分:-1)
另一种方式:
create function Fact(@num int)
returns bigint
as
begin
declare @i int = 1
while @num>1
begin
set @i = @num * @i
set @num=@num-1
end
return @i
end
select dbo.Fact(5)
答案 11 :(得分:-1)
MS-SQL:阶乘从0到88:
with tb1 as (
select 10000000 as b, 1 as n,
0 as t18, 0 as t17, 0 as t16, 0 as t15, 0 as t14, 0 as t13, 0 as t12, 0 as t11, 0 as t10, 0 as t9, 0 as t8, 0 as t7, 0 as t6, 0 as t5, 0 as t4, 0 as t3, 0 as t2, 0 as t1, 1 as t0
union all
select
tb1.b,
tb1.n + 1,
(tb1.t18 * tb1.n) + ((tb1.t17 * tb1.n) + ((tb1.t16 * tb1.n) + ((tb1.t15 * tb1.n) + ((tb1.t14 * tb1.n) + ((tb1.t13 * tb1.n) + ((tb1.t12 * tb1.n) + ((tb1.t11 * tb1.n) + ((tb1.t10 * tb1.n) + ((tb1.t9 * tb1.n) + ((tb1.t8 * tb1.n) + ((tb1.t7 * tb1.n) + ((tb1.t6 * tb1.n) + ((tb1.t5 * tb1.n) + ((tb1.t4 * tb1.n) + ((tb1.t3 * tb1.n) + ((tb1.t2 * tb1.n) + ((tb1.t1 * tb1.n) + (tb1.t0 * tb1.n) / tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b,
((tb1.t17 * tb1.n) + ((tb1.t16 * tb1.n) + ((tb1.t15 * tb1.n) + ((tb1.t14 * tb1.n) + ((tb1.t13 * tb1.n) + ((tb1.t12 * tb1.n) + ((tb1.t11 * tb1.n) + ((tb1.t10 * tb1.n) + ((tb1.t9 * tb1.n) + ((tb1.t8 * tb1.n) + ((tb1.t7 * tb1.n) + ((tb1.t6 * tb1.n) + ((tb1.t5 * tb1.n) + ((tb1.t4 * tb1.n) + ((tb1.t3 * tb1.n) + ((tb1.t2 * tb1.n) + ((tb1.t1 * tb1.n) + (tb1.t0 * tb1.n) / tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)%tb1.b,
((tb1.t16 * tb1.n) + ((tb1.t15 * tb1.n) + ((tb1.t14 * tb1.n) + ((tb1.t13 * tb1.n) + ((tb1.t12 * tb1.n) + ((tb1.t11 * tb1.n) + ((tb1.t10 * tb1.n) + ((tb1.t9 * tb1.n) + ((tb1.t8 * tb1.n) + ((tb1.t7 * tb1.n) + ((tb1.t6 * tb1.n) + ((tb1.t5 * tb1.n) + ((tb1.t4 * tb1.n) + ((tb1.t3 * tb1.n) + ((tb1.t2 * tb1.n) + ((tb1.t1 * tb1.n) + (tb1.t0 * tb1.n) / tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)%tb1.b,
((tb1.t15 * tb1.n) + ((tb1.t14 * tb1.n) + ((tb1.t13 * tb1.n) + ((tb1.t12 * tb1.n) + ((tb1.t11 * tb1.n) + ((tb1.t10 * tb1.n) + ((tb1.t9 * tb1.n) + ((tb1.t8 * tb1.n) + ((tb1.t7 * tb1.n) + ((tb1.t6 * tb1.n) + ((tb1.t5 * tb1.n) + ((tb1.t4 * tb1.n) + ((tb1.t3 * tb1.n) + ((tb1.t2 * tb1.n) + ((tb1.t1 * tb1.n) + (tb1.t0 * tb1.n) / tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)%tb1.b,
((tb1.t14 * tb1.n) + ((tb1.t13 * tb1.n) + ((tb1.t12 * tb1.n) + ((tb1.t11 * tb1.n) + ((tb1.t10 * tb1.n) + ((tb1.t9 * tb1.n) + ((tb1.t8 * tb1.n) + ((tb1.t7 * tb1.n) + ((tb1.t6 * tb1.n) + ((tb1.t5 * tb1.n) + ((tb1.t4 * tb1.n) + ((tb1.t3 * tb1.n) + ((tb1.t2 * tb1.n) + ((tb1.t1 * tb1.n) + (tb1.t0 * tb1.n) / tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)%tb1.b,
((tb1.t13 * tb1.n) + ((tb1.t12 * tb1.n) + ((tb1.t11 * tb1.n) + ((tb1.t10 * tb1.n) + ((tb1.t9 * tb1.n) + ((tb1.t8 * tb1.n) + ((tb1.t7 * tb1.n) + ((tb1.t6 * tb1.n) + ((tb1.t5 * tb1.n) + ((tb1.t4 * tb1.n) + ((tb1.t3 * tb1.n) + ((tb1.t2 * tb1.n) + ((tb1.t1 * tb1.n) + (tb1.t0 * tb1.n) / tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)%tb1.b,
((tb1.t12 * tb1.n) + ((tb1.t11 * tb1.n) + ((tb1.t10 * tb1.n) + ((tb1.t9 * tb1.n) + ((tb1.t8 * tb1.n) + ((tb1.t7 * tb1.n) + ((tb1.t6 * tb1.n) + ((tb1.t5 * tb1.n) + ((tb1.t4 * tb1.n) + ((tb1.t3 * tb1.n) + ((tb1.t2 * tb1.n) + ((tb1.t1 * tb1.n) + (tb1.t0 * tb1.n) / tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)%tb1.b,
((tb1.t11 * tb1.n) + ((tb1.t10 * tb1.n) + ((tb1.t9 * tb1.n) + ((tb1.t8 * tb1.n) + ((tb1.t7 * tb1.n) + ((tb1.t6 * tb1.n) + ((tb1.t5 * tb1.n) + ((tb1.t4 * tb1.n) + ((tb1.t3 * tb1.n) + ((tb1.t2 * tb1.n) + ((tb1.t1 * tb1.n) + (tb1.t0 * tb1.n) / tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)%tb1.b,
((tb1.t10 * tb1.n) + ((tb1.t9 * tb1.n) + ((tb1.t8 * tb1.n) + ((tb1.t7 * tb1.n) + ((tb1.t6 * tb1.n) + ((tb1.t5 * tb1.n) + ((tb1.t4 * tb1.n) + ((tb1.t3 * tb1.n) + ((tb1.t2 * tb1.n) + ((tb1.t1 * tb1.n) + (tb1.t0 * tb1.n) / tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)%tb1.b,
((tb1.t9 * tb1.n) + ((tb1.t8 * tb1.n) + ((tb1.t7 * tb1.n) + ((tb1.t6 * tb1.n) + ((tb1.t5 * tb1.n) + ((tb1.t4 * tb1.n) + ((tb1.t3 * tb1.n) + ((tb1.t2 * tb1.n) + ((tb1.t1 * tb1.n) + (tb1.t0 * tb1.n) / tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)%tb1.b,
((tb1.t8 * tb1.n) + ((tb1.t7 * tb1.n) + ((tb1.t6 * tb1.n) + ((tb1.t5 * tb1.n) + ((tb1.t4 * tb1.n) + ((tb1.t3 * tb1.n) + ((tb1.t2 * tb1.n) + ((tb1.t1 * tb1.n) + (tb1.t0 * tb1.n) / tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)%tb1.b,
((tb1.t7 * tb1.n) + ((tb1.t6 * tb1.n) + ((tb1.t5 * tb1.n) + ((tb1.t4 * tb1.n) + ((tb1.t3 * tb1.n) + ((tb1.t2 * tb1.n) + ((tb1.t1 * tb1.n) + (tb1.t0 * tb1.n) / tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)%tb1.b,
((tb1.t6 * tb1.n) + ((tb1.t5 * tb1.n) + ((tb1.t4 * tb1.n) + ((tb1.t3 * tb1.n) + ((tb1.t2 * tb1.n) + ((tb1.t1 * tb1.n) + (tb1.t0 * tb1.n) / tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)%tb1.b,
((tb1.t5 * tb1.n) + ((tb1.t4 * tb1.n) + ((tb1.t3 * tb1.n) + ((tb1.t2 * tb1.n) + ((tb1.t1 * tb1.n) + (tb1.t0 * tb1.n) / tb1.b)/tb1.b)/tb1.b)/tb1.b)/tb1.b)%tb1.b,
((tb1.t4 * tb1.n) + ((tb1.t3 * tb1.n) + ((tb1.t2 * tb1.n) + ((tb1.t1 * tb1.n) + (tb1.t0 * tb1.n) / tb1.b)/tb1.b)/tb1.b)/tb1.b)%tb1.b,
((tb1.t3 * tb1.n) + ((tb1.t2 * tb1.n) + ((tb1.t1 * tb1.n) + (tb1.t0 * tb1.n) / tb1.b)/tb1.b)/tb1.b)%tb1.b,
((tb1.t2 * tb1.n) + ((tb1.t1 * tb1.n) + (tb1.t0 * tb1.n) / tb1.b)/tb1.b)%tb1.b,
((tb1.t1 * tb1.n) + (tb1.t0 * tb1.n) / tb1.b)%tb1.b,
(tb1.t0 * tb1.n) % tb1.b
from tb1 where tb1.n < 89
)
, t2 as (
select tb1.n - 1 as N,
FORMAT(tb1.t18, '0000000') +
FORMAT(tb1.t17, '0000000') + FORMAT(tb1.t16, '0000000') + FORMAT(tb1.t15, '0000000') +
FORMAT(tb1.t14, '0000000') + FORMAT(tb1.t13, '0000000') + FORMAT(tb1.t12, '0000000') +
FORMAT(tb1.t11, '0000000') + FORMAT(tb1.t10, '0000000') + FORMAT(tb1.t9, '0000000') +
FORMAT(tb1.t8, '0000000') + FORMAT(tb1.t7, '0000000') + FORMAT(tb1.t6, '0000000') +
FORMAT(tb1.t5, '0000000') + FORMAT(tb1.t4, '0000000') + FORMAT(tb1.t3, '0000000') +
FORMAT(tb1.t2, '0000000') + FORMAT(tb1.t1, '0000000') + FORMAT(tb1.t0, '0000000') as FACT
from tb1
)
select t2.N, SUBSTRING(t2.FACT, PATINDEX('%[^0]%', t2.FACT+'.'), LEN(t2.FACT))
from t2
order by t2.N