子查询中的order by子句导致错误

时间:2014-07-23 15:17:57

标签: sql sql-server

为什么此查询不起作用?

SELECT * FROM
(
    SELECT
        p.FirstName as name,
        DATEDIFF(YYYY,p.dob,GETDATE()) AS age
    FROM Person.Person p 
    WHERE p.dob is not null
    ORDER BY age
) a

在SQL Server中抛出以下错误。

  

ORDER BY子句在视图,内联函数中派生无效   表,子查询和公用表表达式,除非TOP,OFFSET   或者也指定了FOR XML。

当我只执行内部子查询时,它会完美地完成。

4 个答案:

答案 0 :(得分:2)

您的子查询无法按错误状态排序。试试这个

select * from
(
select 
    p.FirstName as name,
    DATEDIFF(YYYY,p.dob,GETDATE()) AS age
from Person.Person p 
where p.dob is not null

) a
ORDER BY a.age

答案 1 :(得分:1)

select a.name,a.age from
(
select 
    p.FirstName as name,
    DATEDIFF(YYYY,p.dob,GETDATE()) AS age
from Person.Person p 
where p.dob is not null

) a
ORDER BY a.age

答案 2 :(得分:1)

如前所述,order by不允许在子查询中。

原因是定义的子查询由另一个查询调用。正是外部查询确定结果的顺序。订购中间结果集对最终结果的顺序没有影响。因此,sql server不允许您将子命令添加到子查询中,以防止您甚至认为它在查询中有效。如果它允许订单,微软会得到大量的错误报告:订单不起作用,当它完美运行时,它不会应用于最终结果集。

编辑以回答有关订单是否可以提高加入效果的问题。

SQL Server将确定连接两个结果集的最佳方法。在您的情况下,特别是如果id是聚簇键,它可能会以id顺序选择子查询,然后根据该顺序运行连接(合并连接)。但它并不是必须的。如果你的where子句限制返回的行足够多,那么它可以决定更快做其他事情,如嵌套循环连接。您正试图通过订单帮助优化器。可能它会在内部执行订单,您可以检查执行计划以查看。但是,它可以选择进行不同的连接,它认为会更快。

让sql server优化自己。 Sql是描述您想要的内容的语言,而不是如何获取它。我希望这些表中的这些列按此顺序排列。让sql server决定中间顺序是否允许它更快地运行。不要试图强迫它以某种方式运行。它比我们任何一方都更了解它的功能和数据。

答案 3 :(得分:0)

从RA角度的SQL Server实现中排序内部查询没有意义。返回或检索行时,SQL Server不保证也不承担任何顺序; talbe只是一个无序的关系,可以使用order by子句以特定顺序呈现。 由于RA是一个代数闭包,表达式的结果也是一个Relation,这意味着子查询的结果也是一个Relation,其中返回行的顺序不能保证。因此,子查询中的order by对外部查询的影响与物理表中行的顺序对select语句的影响相同,即无效。

相关问题