在 PostgreSQL 中,我经常想做一些事情,比如找到7的阶乘。我可以很简单地用
SELECT 7!;
-- PostgreSQL is so full featured
-- it even supports a prefix-factorial
SELECT !!7;
Run Code Online (Sandbox Code Playgroud)
甚至Excel 也有FACT
,
=FACT(7)
Run Code Online (Sandbox Code Playgroud)
如何使用 SQL Server 2017 Enterprise 做到这一点?
Sol*_*zky 15
我不知道有一个内置函数可以做到这一点。你需要自己滚动。这是我如何做到的:
SELECT SQL#.Math_Factorial(5); -- 120
Run Code Online (Sandbox Code Playgroud)
该Math_Factorial功能在免费版本的SQL# SQLCLR库(我写)。
或者
如果您不需要函数/UDF 形式的它,那么执行以下操作可能更有效:
DECLARE @BaseNumber INT = 5,
@Result BIGINT = 1;
;WITH cte AS
(
SELECT TOP (@BaseNumber) ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS [Num]
FROM sys.columns
ORDER BY Num
)
SELECT @Result *= [Num]
FROM cte;
SELECT @Result;
-- 120
Run Code Online (Sandbox Code Playgroud)
上面显示的两种方法都考虑了0
作为“BaseNumber”传入的“特殊”条件,它返回1
而不是0
.
SELECT SQL#.Math_Factorial(0); -- 1
Run Code Online (Sandbox Code Playgroud)
对于 T-SQL 方法,只需 make@BaseNumber = 0
它将返回1
(无需为此再次复制和粘贴它)。
小智 8
与 PostgreSQL 相比,您可能会对 SQL Server 中的结果感到失望(它能够处理非常大的数字,例如30000!而不会损失精度)。
在SQL Server33!
是高,你可以用精确的精度,同时走170!
是高,你可以都去(171!
是1.24E309
超过的限制float
)。
所以你可以预先计算它们并将它们存储在一个带有 values 的表中0 ... 170
。如果使用压缩,这适合单个数据页。
CREATE TABLE dbo.Factorials
(
N TINYINT PRIMARY KEY WITH (DATA_COMPRESSION = ROW),
FactorialExact NUMERIC(38, 0) NULL,
FactorialApprox FLOAT NOT NULL
);
WITH R(N, FactorialExact, FactorialApprox)
AS (SELECT 0,
CAST(1 AS NUMERIC(38, 0)),
1E0
UNION ALL
SELECT R.N + 1,
CASE WHEN R.N < 33 THEN ( R.N + 1 ) * R.FactorialExact END,
CASE WHEN R.N < 170 THEN ( R.N + 1 ) * R.FactorialApprox END
FROM R
WHERE R.N < 170)
INSERT INTO dbo.Factorials
(N,
FactorialExact,
FactorialApprox)
SELECT N,
FactorialExact,
FactorialApprox
FROM R
OPTION (MAXRECURSION 170);
Run Code Online (Sandbox Code Playgroud)
或者,以下将为 @N 提供最多 10 的准确结果 - 并为 11+ 提供近似值(如果各种函数/常量(PI()
, EXP()
, POWER()
)与DECIMAL
类型一起工作,但它们FLOAT
仅适用于类型,则会更准确):
DECLARE @N integer = 10;
SELECT
CONVERT
(
DECIMAL(38,0),
SQRT(2 * PI() * @N) *
POWER(@N/EXP(1), @N) *
EXP(1.0/12.0/@N + 1.0/360.0/POWER(@N, 3))
);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2823 次 |
最近记录: |