如何在sql中计算大的组合数量

How to calculate big combinatorics amount in tsql

在 sql2014 中,我有一个 table,其中包含 4 个整数(W、X、Y、Z)和一个 bigint B。 B = C(X,Z)*C(W-X;Y-Z) 其中C(n,k)代表从n个对象中取出k个对象的组合,即通常的n!/[k!(n-k)!]

W,X,Y,Z的最大值为40所以最大的B为1.37847E+11 我可以使用 Excel(使用函数 COMBIN)计算出正确的值,但我不能在 SQL 中计算出相同的值。我可以用我需要的 W、X、Y、Z 的所有组合生成 table,但是当我尝试为大值计算 B 时,我不知道如何处理“40!”之类的东西。

我想使用预插入阶乘值的 CTE,例如:

;WITH factorials AS(
SELECT 2 as N, 2 AS F
UNION ALL
SELECT 3,6
UNION ALL...
)

但我不知道如何存储 40!等等。

使用 .NET 填充 table 不是一个选项,它应该由 SQL 完成。

我什至想过像之前的 CTE 一样使用 table 并将阶乘存储在两列或三列中,第一列存储数十亿,第二列存储数十亿等等(使用 INT),但随后我不知道如何对这样存储的数字进行除法,如 (Ax10^9+B)/(Cx10^9+D)。

如何在 tsql 中管理大于 bigint 的整数?

请在此处检查小数和数字数据类型:https://technet.microsoft.com/en-us/library/ms187746.aspx

我确信这不是一个完整的解决方案,但也许它会给您一些关于如何开始的想法。也许您可以将其设为存储过程并传入 @n 和 @k

当我将其转换回 BIGINT 时,使用 DOUBLE 似乎不会引起任何问题。也许其他人可以评论这样做的明显危险。

DECLARE @final_value DOUBLE PRECISION
DECLARE @n INT = 40
DECLARE @k INT = 20

;WITH CTE AS 
(
SELECT 1 AS num,CAST(1 AS DOUBLE PRECISION) AS factorial
UNION ALL
SELECT num+1,CAST(factorial*(num+1)AS DOUBLE PRECISION) FROM CTE
WHERE CTE.num < 40
)

SELECT * INTO #temp_numbers FROM CTE 

SET @final_value = (SELECT factorial FROM #temp_numbers WHERE num = @n) /
    (SELECT factorial FROM #temp_numbers WHERE num = @k) / 
    (SELECT factorial FROM #temp_numbers WHERE num = (@n-@k))  

PRINT CAST(@final_value AS BIGINT)
DROP TABLE #temp_numbers