【问题标题】:ORDER BY in both queries of the EXCEPT clauseEXCEPT 子句的两个查询中的 ORDER BY
【发布时间】:2014-05-01 15:28:10
【问题描述】:

我希望在 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

例如:

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。

【问题讨论】:

  • 哇...select * 已经够糟糕了,但是当我们没有架构可以使用时,情况就更糟了。
  • @ebyrob 我使用 select * 只是为了说明,它可以是 * 以外的任何东西
  • @thunder nah,您确实有足够的信息在这里得到一个好的答案。我只是有心情。
  • @stakx 我正在寻找适用于所有数据库的东西。
  • 实际上,TOP 不是 ANSI 标准,你的开局很糟糕。

标签: sql ansi-sql


【解决方案1】:

我同意,这应该可以工作,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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 我添加了一个示例,说明为什么两个查询都需要 order by
    • 使用select...intoselect top...order by 查询的结果插入到几个临时表中。然后执行except
    • 临时表似乎是可行的选择,但不是那么优雅,不是吗?或者这只是我的想法。
    • @Thunder 如果您担心优雅,请阅读我链接的文章。请注意,“优雅”的三重查询效率非常低。
    【解决方案3】:

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

    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 答案。

    【讨论】:

      【解决方案4】:

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

      如果您查看集合操作的syntax definitionunionunion allintersectexcept),您会发现它们引用了“query_expression”和“query specification”:

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

      逻辑表明这些是select 声明的全部荣耀。但他们不是。 select 语句的全部荣耀包括四个未包含在其中的子句:withfororder byoption。所以,那些是不允许的。

      也就是说,我确实认为上述表达式不正确,因为在我阅读文档时,&lt;query_specification&gt; 包含 into。更准确的规范将与 union 相同:

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

      我不相信into 将被允许用于使用集合操作的查询的两个部分。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多