在PostgreSQL中,我经常想做一些事情,例如找到7 的阶乘。
SELECT 7!;
-- PostgreSQL is so full featured
-- it even supports a prefix-factorial
SELECT !!7;
甚至Excel都有FACT
,
=FACT(7)
如何使用SQL Server 2017 Enterprise做到这一点?
在PostgreSQL中,我经常想做一些事情,例如找到7 的阶乘。
SELECT 7!;
-- PostgreSQL is so full featured
-- it even supports a prefix-factorial
SELECT !!7;
甚至Excel都有FACT
,
=FACT(7)
如何使用SQL Server 2017 Enterprise做到这一点?
Answers:
我不知道有内置函数可以执行此操作。您需要自己动手。这是我的方法:
SELECT SQL#.Math_Factorial(5); -- 120
该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
上面显示的两种方法都考虑了0
以“ BaseNumber” 传入的“特殊”条件,并且返回1
而不是0
。
SELECT SQL#.Math_Factorial(0); -- 1
对于T-SQL方法,只需make即可@BaseNumber = 0
返回1
(无需为此再次复制并粘贴到此处)。
与PostgreSQL相比,您可能会对SQL Server中的结果感到失望(PostgreSQL能够处理非常大的数字,例如30000 !,而不会损失精度)。
在SQL Server 33!
是高,你可以用精确的精度,同时走170!
是高,你可以都去(171!
是1.24E309
超过的限制float
)。
因此,您可以预先计算它们,并将它们存储在具有值的表中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);
另外,下面将给出@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))
);