EXCEPT子句的两个查询中的ORDER BY

时间:2014-05-01 15:28:10

标签: sql ansi-sql

我想在ANSI SQL中实现分页查询。

我在SQL Server中尝试了以下查询,但它不允许它:

select top 20 * from MyTable order by id  
except
select top 10 * from MyTable order by id

但以下工作正常:

select top 20 * from MyTable 
except
select top 10 * from MyTable order by id

e.g:

input   expected result
20      11
11      13
25      14
6       16
4       17
2       18
1       19
9       20
3       25
7       
8       
16      
17      
18      
13      
14      
19      
10      
5   

从上面的例子中可以看出,如果我们不能写第一个ORDER BY子句,那么结果将不会具有值20,11,25。

4 个答案:

答案 0 :(得分:4)

我同意,这应该有效,order bytop一起仍然会产生一个表(仅选择order by生成一个游标,因此不能用作选择源)。

当然,您可以轻松解决此限制:

select * from (select top 20 * from MyTable order by id) x
except
select * from (select  top 10 * from MyTable order by id) y

答案 1 :(得分:3)

order by子句只需在except运算符比较最后一次出现的查询后出现一次。 order by是在逻辑查询处理阶段要评估的最后一个子句。

答案 2 :(得分:1)

这篇文章从上面的评论中挖掘出来很棒:

http://www.codeproject.com/Articles/6936/Paging-of-Large-Resultsets-in-ASP-NET

特别是Asc-Desc方法:

  

此方法在子查询中使用默认排序,然后应用   反向排序。原理就是这样

DECLARE @temp TABLE (
    PK  /* PK Type */ NOT NULL PRIMARY 
)

INSERT INTO @temp 
SELECT TOP @PageSize PK FROM (
    SELECT TOP (@StartRow + @PageSize) 
    PK, 
    SortColumn /*If sorting column is defferent from the PK, SortColumn must 
             be fetched as well, otherwise just the PK is necessary */ 
    ORDER BY SortColumn /* default order – typically ASC */) 
ORDER BY SortColumn /* reversed default order – typically DESC */

SELECT ... FROM Table JOIN @Temp temp ON Table.PK = temp.PK 
ORDER BY SortColumn /* default order */

当然,表现并不好,但它应该适用于所有地方。

PS - 我认为你作弊,你得到了一个分页答案 EXCEPT ORDER BY答案。

答案 3 :(得分:0)

这个答案可能是一个评论,但documentation在这一点上是微妙的,需要一些解释。

如果您查看设置操作的syntax definitionunionunion allintersectexcept),您会看到它们引用“query_expression”和“查询规范”:

{ <query_specification> | ( <query_expression> ) } 
{ EXCEPT | INTERSECT }
{ <query_specification> | ( <query_expression> ) }

逻辑会暗示这些是select陈述的全部荣耀。但他们不是。 select语句的完整荣耀包括以下未包含的四个条款:withfororder byoption。所以,不允许这些。

那就是说,我认为上面的表达方式不正确,因为<query_specification>在我阅读文档时包含into。更准确的规范与union

相同
{ <query_specification> | ( <query_expression> ) } 
{ EXCEPT | INTERSECT }
{ <query_expression> }

我不相信在使用set操作的查询的两个部分都允许into