到目前为止我发现了什么:
Microsoft’s Definition“使用一组特定的输入值调用确定性函数时,它们总是返回相同的结果,并给出相同的数据库状态.”
所以在Set理论表中
雇员
Employee Salary Sue Right 1.00 Robin Page 1.00 Phil Factor 1.00
和
雇员2
Employee Salary Phil Factor 1.00 Sue Right 1.00 Robin Page 1.00
是相同的.但排名函数返回不同的值:
CREATE TABLE [dbo].[Employees]( --[ID] [int] IDENTITY(1,1) NOT NULL,[Employee] [varchar](150) NOT NULL,[Salary] [smallmoney] NULL,) ON [PRIMARY] GO CREATE TABLE [dbo].[Employees2]( --[ID] [int] IDENTITY(1,) ON [PRIMARY] INSERT INTO [dbo].[Employees] ([Employee],[Salary]) VALUES ('Sue Right',1),('Robin Page',('Phil Factor',1 ) GO INSERT INTO [dbo].[Employees2] ([Employee],[Salary]) VALUES ('Phil Factor',1 ),('Sue Right',1) GO SELECT RANK() OVER ( ORDER BY Salary) AS [Rank],DENSE_RANK() OVER (ORDER BY Salary ) AS [Dense_rank],[Employee] FROM dbo.Employees SELECT RANK() OVER ( ORDER BY Salary) AS [Rank],[Employee] FROM dbo.Employees2 SELECT NTILE(3) OVER ( ORDER BY SALARY ),[Employee] FROM dbo.Employees SELECT NTILE(3) OVER ( ORDER BY SALARY ),[Employee] FROM dbo.Employees2
解决方法
According to official Microsoft BOL DENSE_RANK is nondeterministic (RANK()). But according to Ranking Functions by Itzik Ben-Gan “… the RANK() and DENSE_RANK() functions are always deterministic”. Who is right?
他们都是对的,因为他们使用“确定性”这个词的不同含义.
从sql Server优化器的角度来看,“确定性”具有非常精确的含义;窗口和排名函数之前存在的含义已添加到产品中.对于优化器,“deterministic”属性定义在优化期间函数是否可以在其内部树结构中自由复制.这对于非确定性函数来说是不合法的.
这里的确定性意味着:无论调用多少次,函数的确切实例总是为同一输入返回相同的输出.根据定义,对于窗口函数来说,这永远不会成立,因为作为(单行)标量函数,它们不会在行内或跨行返回相同的结果.简单地说,使用ROW_NUMBER作为示例:
The
ROW_NUMBER
function returns different values for different rows (by definition!),so for optimization purposes it is nondeterministic
这是BOL正在使用的意义.
Itzik对整个结果的决定论提出了不同的观点.在有序输入集(具有合适的打破平局)上,输出是“确定性”序列.这是一个有效的观察,但它不是在查询优化期间重要的“确定性”质量.