过滤ROW_NUMBER()正在改变结果

时间:2015-02-19 03:24:00

标签: sql sql-server sql-server-2008 row-number

我确实实现了自己的OData服务,该服务接受SQL语句并使用ROW_NUMBER()应用top / skip过滤器。到目前为止,大多数语句测试都运行良好,除了涉及2级左连接的声明。出于某种原因,我无法解释,当我在行号列上应用where子句时,sql返回的数据正在改变。

为了便于阅读(和测试),我删除了大部分sql以仅保留错误部分。基本上,您有一个患者表,可能有0到N诊断,诊断可能有0到N个治疗:

SELECT RowNumber, PatientID, DiagnosticID, TreatmentID 
FROM 
(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNumber
         , *
    FROM PATIENTS
    LEFT JOIN DIAGNOSTICS ON DIAGNOSTICS.PatientID = PATIENTS.PatientID
    LEFT JOIN TREATMENTS ON TREATMENTS.DiagnosticID = DIAGNOSTICS.DiagnosticID
) AS Wrapper
--WHERE RowNumber BETWEEN 1 AND 10
--If I uncomment the line above, I'll get 10 lines that differs from the first 10 line of this query

这是我从上面的陈述中得到的结果。左边的结果显示没有WHERE子句的前10行,而右边的结果显示带有WHERE子句的结果。

Results

为了记录,我正在使用SQL Server 2008 R2 SP3。我的应用程序是在C#中,但问题也出现在SQL服务器中,所以我不认为.NET会涉及到这种情况。

修改

关于ORDER BY (SELECT NULL),我刚刚从SO question获取了该代码。但是,只有当语句被排序时,null的顺序才有效...在我的情况下,我忘了添加order by子句,这就是为什么我得到一些随机排序。

1 个答案:

答案 0 :(得分:4)

首先让我问:你为什么期望它是一样的?或者更确切地说,为什么你期望它特别是什么?您还没有强制执行排序,因此查询优化器可以自由使用任何执行运算符最有效(根据其成本方案)。添加WHERE子句时,计划将发生变化,结果的自然顺序也会不同。例如,在添加联接或子查询时也会发生这种情况。

如果希望结果按特定顺序返回,则需要实际使用ORDER BY窗口函数的ROW_NUMBER()子句。我不确定你为什么要SELECT NULL订购,但我可以向你保证这是问题。