我想在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。
答案 0 :(得分:4)
我同意,这应该有效,order by
与top
一起仍然会产生一个表(仅选择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 definition(union
,union all
,intersect
,except
),您会看到它们引用“query_expression”和“查询规范”:
{ <query_specification> | ( <query_expression> ) }
{ EXCEPT | INTERSECT }
{ <query_specification> | ( <query_expression> ) }
逻辑会暗示这些是select
陈述的全部荣耀。但他们不是。 select
语句的完整荣耀包括以下未包含的四个条款:with
,for
,order by
和option
。所以,不允许这些。
那就是说,我认为上面的表达方式不正确,因为<query_specification>
在我阅读文档时包含into
。更准确的规范与union
:
{ <query_specification> | ( <query_expression> ) }
{ EXCEPT | INTERSECT }
{ <query_expression> }
我不相信在使用set操作的查询的两个部分都允许into
。