为什么使用确定性函数 STDEV() 会得到不确定性结果?

J.D*_*.D. 5 sql-server aggregate cte determinism sql-server-2016

这是我尝试运行的查询类型:

WITH CTE_Ordered AS
(
  SELECT *, ROW_NUMBER() OVER (PARTITION BY PartitionField ORDER BY DateField) AS PartitionRowId
  FROM SourceTable
),
CTE_Top1_PerPartition AS
(
  SELECT *
  FROM CTE_Ordered
  WHERE PartitionRowId = 1
),
CTE_Calculations AS
(
  SELECT AVG(NumberField1) AS NumberField1_Avg, StdDev.StdDev AS NumberField1_StdDev
  FROM CTE_Top1_PerPartition 
  CROSS JOIN
  (
     SELECT STDEV(NumberField1) AS StdDev
     FROM CTE_Top1_PerPartition 
  ) AS StdDev
  GROUP BY StdDev.StdDev
)

-- Final Select
SELECT *
FROM CTE_Calculations
Run Code Online (Sandbox Code Playgroud)

每次运行最终选择时,即使 SourceTable 是孤立的并且不会更改,我的 NumberField1_StdDev 值也会更改。

我注意到如果我首先将 CTE_Top1_PerPartition 选择到临时表中,然后从该临时表运行其余的查询,那么我每次都会得到相同的 NumberField1_StdDev 结果。

我猜这与结果在 CTE_Top1_PerPartition CTE 中返回的顺序有关,但我不确定为什么。

Jus*_*ave 15

row_number如果可以存在联系(即具有相同PartitionFieldDateField值的行),则不是确定性的。任何绑定的值都可能PartitionRowId以 1结束,这可能会改变最终结果。

您可以使用rank代替,row_number但这会导致您考虑所有可能不是您想要的绑定行。您还可以更新您的分析函数以添加其他order by条件以确保row_number返回确定性的第一行。