在OrderBy中忽略别名

时间:2009-09-02 11:30:26

标签: sql-server sql-order-by alias

我们的应用程序中有两个表都有ShowOrder列。我们在我们的应用程序中使用NHibernate并使用HQL,我们将这两个表分别按第一个表和第二个表的ShowOrder排序。

以下是我的查询的简化版本:

SELECT pr.Id as Id,pr.Title as Title, pr.ShowOrder as ShowOrder 
FROM Process pr 
    INNER JOIN ProcessGroup prg ON pr.GroupId=prg.Id 
ORDER BY prg.ShowOrder,pr.ShowOrder

一般来说,我们的应用程序没有任何问题。但是我们有一个旧的应用程序和一个转换例程来将其数据库转换为我们的新应用程序数据库。

每当我们将旧数据库转换为新数据库时,SQL Server要执行上述查询时都会发生错误。例外情况说:

  

按列表

的顺序多次指定了一列

如果我们选择没有别名的pr.ShowOrder,一切正常。

如果选择列表中有ShowOrder别名,SQL Server会忽略表别名,并假设pr.ShowOrderprg.ShowOrder相同。

3 个答案:

答案 0 :(得分:12)

这是ANSI SQL的标准行为,并且从2005版本开始被SQL Server采用。

ORDER BY不对源表(FROM子句)中的列值进行操作,而是仅在技术上对SELECT子句(**)中的输出列值进行操作。因此,当您在ORDER BY子句中说“ShowOrder”时,它实际上是在输出列表中使用ShowOrder值(恰好是pr.ShowOrder)。如果要同时使用两个ShowOrders,则应将它们放在具有不同名称的SELECT子句中。

当您使用 source 表别名(技术上应该是)时,不会出现问题的原因是为了与SQL Server 2000兼容,但这是一种危险的兼容性。无论您在ORDER BY中使用什么别名,它实际上只使用输出列表中显示的名称。

(** - 是的,有很多方法,但它们主要是为了提供与先前版本的兼容性。你最好选择标准)。

答案 1 :(得分:10)

答案 2 :(得分:2)

此错误的另一个原因可能是 - 数据库兼容级别设置为“ 2000-mode ”(这可能在您将SQL Server从2000升级到2005或更高版本后发生)。

解决方案:

“SQL Management Studio” - 右键单击​​数据库 - “属性” - “选项” - “兼容级别” - 设置为90或更高。