如何在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
在 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