SQL Server 2005 与 SQL Server 2012 上的按错误排序

Daw*_*wmz 7 sql-server order-by

我有一个由实体框架生成的查询,它在 SQL Server 2005 数据库 (Microsoft SQL Server 2005 - 9.00.5000.00 (X64)) 上返回错误结果,但在 SQL Server 2012 (Microsoft SQL Server 2012 - 11.0.2100.60) 上运行良好。

这是查询:

SELECT 
[Project2].[tableAid] AS [id],     
[Project2].[rank1] AS [rank]   
FROM ( SELECT 
    [Extent1].[id] AS [id], 
    [Extent2].[rank] AS [rank],        
    [Extent4].[rank] AS [rank1]      
    FROM    [dbo].[tableA] AS [Extent1]
    LEFT OUTER JOIN [dbo].[tableB] AS [Extent2] ON ([Extent1].[tableAid] = [Extent2].[tableAid]) AND (896 = [Extent2].[tableBid])
    INNER JOIN [dbo].[tableC] AS [Extent4] ON [Extent1].[tableCid] = [Extent4].[tableCid]        
)  AS [Project2]
ORDER BY [Project2].[rank] DESC
Run Code Online (Sandbox Code Playgroud)

我已经简化了它,但模型是:

TableA
int tableAid
int tableCid

tableB
int tableBid
int tableAid
int rank

tableC
int tableCid
int rank
Run Code Online (Sandbox Code Playgroud)

A 和 B 之间是多对多关系,A 和 C 之间是 1 比 1。

在 SQL Server 2005 上,此查询按结果的排名列排序,而不是按 Project2.rank。如果我将 SELECT 中的 [Project2].[rank1] AS [rank] 替换为 [Project2].[rank1] AS [whatever],则结果将正确排序。但由于这些别名是由 EF 生成的,我无法轻易更改它们。在 SQL Server 2012 上,查询按原样正常工作。

有谁知道这个错误?SQL Server 2005 是否有补丁或一些设置可以避免此问题?

ype*_*eᵀᴹ 13

如果您在 80 (SQL-Server 2000) 的兼容性级别上运行,那么这是预期的行为。它在 2005 版中得到了纠正。

您可以查看MSDN 上的兼容性级别页面,其中列出了差异。在“较低兼容性级别和级别 90 之间的差异”部分中,许多项目之一是:

ORDER BY列表中的列引用绑定到列表中定义的SELECT列时,会忽略列歧义 ,有时会忽略列前缀。这可能会导致结果集以意外的顺序返回。

例如,接受ORDER BY包含单个两部分列 (.)的子句,该列用作对SELECT列表中列的引用 ,但会忽略表别名。考虑以下查询。

SELECT c1 = -c1 FROM t_table AS x ORDER BY x.c1
Run Code Online (Sandbox Code Playgroud)

执行时,列前缀在ORDER BY. 排序操作未按预期在指定的源列 (x.c1) 上发生;相反,它发生在查询中定义的派生 c1 列上。此查询的执行计划显示,首先计算派生列的值,然后对计算值进行排序。

这正是你所描述的。

最简单的解决方法是不要对子查询中的一列和主查询中的另一列使用相同的别名。

  • +1 不错,需要在 [这里] 补充一下(http://dba.stackexchange.com/questions/44908/what-is-the-actual-behavior-of-compatibility-level-80/44912#44912) (2认同)
  • 你是对的,我的 sql 2005 设置为兼容级别 80 !很高兴知道。谢谢 ! (2认同)