【发布时间】:2018-07-27 14:13:46
【问题描述】:
我在两个不同的SQL Server instances 上运行两个查询,一个是"13.0.4474.0",另一个是"13.0.4411.0"。
他们计算同一组大约8K bigint numbers 的STDEV。
STDEV 与众不同!
我确信数字是相同的,因为在应用 STDEV 之前,我选择了所有数字并进行比较。他们。是。这。相同的。 (我把这两组放在 Excel 中,对它们进行排序并在各行上取差异。它总是出来 0,所以它们是相同的)
- 他们的
Sum是一样的。 - 他们的
Count是一样的。
STDEV 略有不同:
2880.01921436887 and 2880,01956854958
如果我在Excel 中计算相同数字的STDEV,我会得到第三个数字,但在这种情况下,谁在乎呢,这一定是由于两个程序的实现中的某些问题。
但是为什么在同一个 SQL Server 中呢?
我使用的查询没有OVER nor ORDER BY(这使得函数不确定)
这是第一台机器上的代码:
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT
COUNT_BIG(*) AS C,
SUM(CAST(MyBigintField AS BIGINT)) AS S,
STDEV(MyBigintField) AS D
FROM
dbo.myTable
WHERE
MyBigintField >= 108000000
AND MyBigintField < 108010000
这些数字不会被任何进程更改。选择不断吐出相同的两个不同的数字。
在第二台机器上查询是完全一样的,除了字段和表的名称,因为我在另一台机器上。再一次,如果我只是用同样的查询收集数字(只是使用 * 而不是 COUNT、SUM、STDEV),我会得到相同的数字。
我做了很多尝试,我发现如果我将 1 加到一台机器上最大的 bigint 数字上,那么我得到的 STDEV 与第二台机器上的相同。如果我在任何其他数字上只加 1,ST.DEV 不会改变,这是更自然的事情,因为这些数字大约是 1 亿,它们是 8 千,所以只在其中一个上加 1不应更改前 11 位小数的 st.dev。
我猜是因为四舍五入,但我不能完全理解。
[编辑]
过了一会儿,我发现了这个非常奇怪的东西:
DECLARE @min as BIGINT
DECLARE @max as BIGINT
DECLARE @step as BIGINT
SET @min = 1900000001
SET @max = 1900000050
SET @step = 1
;WITH mycte AS (
SELECT @min AS i
UNION ALL
SELECT i + @step
FROM mycte
WHERE i <= @max - @step
)
SELECT COUNT(*) myCount, stdev(i) myStDev
FROM mycte
OPTION (MAXRECURSION 0)
这给了我 myCount = 50(正确)和 myStDev = 0(在两台机器上) 我检查了一下,CTE 正确地给了我 1900000001 和 1900000050(包括两者)的 50 个数字。
这怎么可能?
如果我再试一次,但范围上升到 1900000150,则 STDev 与 0 不同,但它似乎与使用 Excel 计算的不同(我尝试了 ST.DEV.P 和 ST.DEV.S)
也许这与我正在处理值非常接近 maxint 的 bigint 数有关?
【问题讨论】:
-
dfdundako:为什么“没有研究”?我花了最后一个小时试图理解这种想法。你认为我在使用 OVER 的情况下发现了函数的非确定性方面吗?我阅读了文档。这是研究!如果确实有这种差异的原因,为什么这个问题没有用?我不同意你的修改
-
向我们展示您的代码
-
@JohannesWentu 我说了什么吗?我编辑了一些内容并更改了拼写。
-
问题上有一个 -1 表示:“这个问题没有表现出任何努力 bla bla bla ...”。既然你是唯一一个在做这件事的人,我猜是你。如果我错了,我很抱歉给你发了邮件。寻求帮助并在 2 分钟后被否决是非常令人沮丧的。如果我有办法将我的批评重定向到正确的人,请让我知道并接受我的借口
-
我自己进行了计算以确认 SD 计算,但它没有得到它们的值 - 您是否熟悉如何通过求和等计算 SD?我会把我的测试代码发给你
标签: sql-server standard-deviation