SQL Functions - factorial

前端 未结 12 1354
傲寒
傲寒 2020-11-30 14:55

I am a beginner in SQL Functions. What is the best way to create a function for factorial in SQL Server- Say 10!

相关标签:
12条回答
  • 2020-11-30 15:25

    /* Print Factorial Sequence*/

    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);
    
    0 讨论(0)
  • 2020-11-30 15:26

    ... for my Set-based method:

    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;
    
    0 讨论(0)
  • 2020-11-30 15:26

    I know I'm a little late here, but it's worth noting that the recursive way that Martin posted does not work for 0.

    This will (forgive me, I was having issues posting the code):


    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
    

    And for the way, way faster version:

    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
    

    This is much faster because I lose the MAX() function which, just like top 1, causes a DISTINCT sort.

    0 讨论(0)
  • 2020-11-30 15:26

    If you are okay with an approximation, use 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
    

    Note that you will have to make a case for 0!, if needed.

    0 讨论(0)
  • 2020-11-30 15:27

    Try this

    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
    
    0 讨论(0)
  • 2020-11-30 15:28

    You asked which is the best way to create a function for factorial in SQL Server. As always, that depends on the context. But if you truly mean it in the generic sense, where performance matters, the best way to go is without a doubt to implement it as a CLR user-defined function.

    https://docs.microsoft.com/en-us/sql/relational-databases/clr-integration-database-objects-user-defined-functions/clr-user-defined-functions?view=sql-server-2017

    You can of course implement the function itself in whatever language you fancy. And a long/bigint doesn't really cut it for a factorial function (a bigint can only fit up to 20!, 21! is arithmetic overflow).

    0 讨论(0)
提交回复
热议问题