我确实实现了自己的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子句的结果。
为了记录,我正在使用SQL Server 2008 R2 SP3。我的应用程序是在C#中,但问题也出现在SQL服务器中,所以我不认为.NET会涉及到这种情况。
修改
关于ORDER BY (SELECT NULL)
,我刚刚从SO question获取了该代码。但是,只有当语句被排序时,null的顺序才有效...在我的情况下,我忘了添加order by子句,这就是为什么我得到一些随机排序。
答案 0 :(得分:4)
首先让我问:你为什么期望它是一样的?或者更确切地说,为什么你期望它特别是什么?您还没有强制执行排序,因此查询优化器可以自由使用任何执行运算符最有效(根据其成本方案)。添加WHERE
子句时,计划将发生变化,结果的自然顺序也会不同。例如,在添加联接或子查询时也会发生这种情况。
如果希望结果按特定顺序返回,则需要实际使用ORDER BY
窗口函数的ROW_NUMBER()
子句。我不确定你为什么要SELECT NULL
订购,但我可以向你保证这是问题。