平均浮动不一致

狗仔队

select返回正确的23,000行
,except将返回60到200行(且行不相同)
,因为select应该返回0,因为select除外select a

PK:[docSVenum1]。[enumID],[docSVenum1]。[valueID],[FTSindexWordOnce]。[wordID]

[tf]是浮点数,
我得到的浮点数不准确,但我天真的认为avg(float)将是可重复的
Avg(float)确实是可重复的

解决办法是什么?
TF在0到1之间,我只需要5个有效数字,
我只需要avg(TF)是要运行的相同数字
Decimal(9,8)给我足够的精度,如果我强制转换为十进制(9,8)除了在正常返回0
,我可以改变[TF]为十进制(9,8),但它会工作和大量的回归测试的一些测试的位是使用[TF]每日接手运行
的是变化[TF ]转换为十进制(9,8)的最佳解决方案?

  SELECT [docSVenum1].[enumID], [docSVenum1].[valueID], [FTSindexWordOnce].[wordID]
       , avg([FTSindexWordOnce].[tf]) AS [avgTFraw]
    FROM [docSVenum1] 
    JOIN [docFieldLock] 
           ON [docFieldLock].[sID] = [docSVenum1].[sID] 
          AND [docFieldLock].[fieldID] = [docSVenum1].[enumID] 
          AND [docFieldLock].[lockID] IN (4, 5) /* secLvl docAdm */ 
    JOIN [FTSindexWordOnce] 
           ON [FTSindexWordOnce].[sID] = [docSVenum1].[sID]
GROUP BY [docSVenum1].[enumID], [docSVenum1].[valueID], [FTSindexWordOnce].[wordID]

except 

  SELECT [docSVenum1].[enumID], [docSVenum1].[valueID], [FTSindexWordOnce].[wordID]
       , avg([FTSindexWordOnce].[tf]) AS [avgTFraw]
    FROM [docSVenum1] 
    JOIN [docFieldLock] 
           ON [docFieldLock].[sID] = [docSVenum1].[sID] 
          AND [docFieldLock].[fieldID] = [docSVenum1].[enumID] 
          AND [docFieldLock].[lockID] IN (4, 5) /* secLvl docAdm */ 
    JOIN [FTSindexWordOnce] 
           ON [FTSindexWordOnce].[sID] = [docSVenum1].[sID]
GROUP BY [docSVenum1].[enumID], [docSVenum1].[valueID], [FTSindexWordOnce].[wordID] 

order by [docSVenum1].[enumID], [docSVenum1].[valueID], [FTSindexWordOnce].[wordID]

在这种情况下,tf是tf-idf的频率项tf
归一化是主观的,不需要很高的精度
Avg(tf)需要在select与select之间保持一致,否则结果不一致。
在具有连接的单选择中,我需要一致的avg (tf)
使用小数和tf的低精度得到了一致的结果

卢卡斯·索兹达(Lukasz Szozda)

这非常类似于:SELECT SUM(...) is non-deterministic when adding the column-values of datatype float

问题在于,如果数据类型(FLOAT/REAL不正确,则对浮点数进行算术运算的顺序就很重要。来自连接的演示:

DECLARE @fl FLOAT = 100000000000000000000
DECLARE @i SMALLINT = 0
WHILE (@i < 100)
BEGIN
    SET @fl = @fl + CONVERT(float, 5000)
    SET @i = @i + 1
END
SET @fl = @fl - 100000000000000000000
SELECT CONVERT(NVARCHAR(40), @fl, 2)
-- 0.000000000000000e+000


DECLARE @fl FLOAT = 0
DECLARE @i SMALLINT = 0
WHILE (@i < 100)
BEGIN
    SET @fl = @fl + CONVERT(float, 5000)
    SET @i = @i + 1
END
SET @fl = @fl + 100000000000000000000
SET @fl = @fl - 100000000000000000000
SELECT @fl
-- 507904

LiveDemo

可能的解决方案:

  • CAST 精确数据类型的所有参数,例如 DECIMAL/NUMERIC
  • 更改表并更改FLOATDECIMAL
  • 您可以尝试强制查询优化器以相同顺序计算总和。

好消息是,当稳定的查询结果对您的应用程序很重要时,您可以通过防止与OPTION(MAXDOP 1)的并行性来强制顺序相同


初始链接似乎已消失。Web存档

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章