【问题标题】:difference in standard deviation calculated on different SQL Servers在不同 SQL Server 上计算的标准差差异
【发布时间】:2018-07-27 14:13:46
【问题描述】:

我在两个不同的SQL Server instances 上运行两个查询,一个是"13.0.4474.0",另一个是"13.0.4411.0"

他们计算同一组大约8K bigint numbersSTDEVSTDEV 与众不同!

我确信数字是相同的,因为在应用 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


【解决方案1】:

这里有一个 CTE 来检查任何一组值 - 如果您更改 'd' 中的 SQL 以返回任何别名为 y 的数字列表,那么您应该得到 'theirSD' 等于 'mySD' - 如果两个不同的服务器给出不同的值,那么我希望 sigma、sigma2 或 n 在它们之间有所不同

我根据 s.d 的定义做了自己的计算,即 (x - mu) 的平方和,然后除以 n-1(在这种情况下)

with d as (select  cast(x as float) y from tempt)
    ,calcs as (select  stdev(y) theirSD, 
                        avg(y) theirAV,
                        sum(y) Sigma,
                        sum(y *y) sigma2,
                        sum(y) / count(0) myAV,
                        count(0) n
                        from d) 
    select *, sqrt((sigma2 - sigma/n * sigma ) / (n-1)) mysd     from calcs

我的公式需要转换为浮点数 - 如果留在 bigint 处,由于四舍五入,它并不太正确,但使用 bigint 后它们的数字看起来仍然正确

我认为您需要检查数据中的 sum(x * x) 因子,然后如果 COUNT 和 SUM(x) 看起来相同,则可能是 Jeroem 假设的数字舍入效应

【讨论】:

    猜你喜欢
    • 2020-01-28
    • 1970-01-01
    • 2016-04-14
    • 2022-01-21
    • 2022-08-15
    • 2017-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多