I am a beginner in SQL Functions. What is the best way to create a function for factorial in SQL Server- Say 10!
-- Iterative method. -- Why Iterative? It is simpler and faster. -- For @N from 0 to 20 this gives an exact result. -- 21 will give an overflow.
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
-- Change the datatype to float and you can get the factorial up to 170. -- 171 will result in an overflow. -- Remark the result will only be accurate over a limited number of positions.
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
-- Ben
Another way:
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)
MS-SQL: Factorial from 0 to 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
A non recursive way
;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
And a recursive way
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
Here is an other method to 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
You need to use a SQL numbers table for this solution. The Select statement updates the declared integer variable for each row in the FROM part with multiplying it with the ordered integer values
Here is a recursive solution:
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