使用 RowCount 对大型结果集分页进行排序






3.33/5 (6投票s)
2004年6月21日
3分钟阅读

55345
大型结果集的快速分页。
引言
本文进一步探讨了 ASP.NET 中大型结果集的分页问题,请参阅:ASP.NET 中大型结果集的分页。
您是否曾经使用过 Microsoft 文档中描述的机制进行分页?
SELECT * FROM PROUCT WHERE ID>@lastProductID
但是,有一个先决条件,根据这个等式,产品 ID 必须是 SQL Server 中的标识列,并且语句不能包含 order by
子句。这就造成了一个限制。如果我们要进行排序呢?本文将简单地说明一种允许排序机制工作的方法。
使用代码
假设我们有一个产品,其中包含两列,一列是 ID,另一列是价格,其中 ID 是唯一的标识列,价格是非唯一的且非空的列,我们想按价格排序。 SQL 是
SELECT * FROM Product ORDER BY Price, ID will give
----------------------------------------
| ID | Price |
----------------------------------------
3 2
4 2
5 2
1 3
2 3
回到基础知识,如果我们想显示产品而不进行排序,假设每个 ASPX 页面中有两个项目,第一页的 SQL 是
SET ROWCOUNT 2 SELECT * FROM PRODUCT WHERER ID>0
第二页的 SQL(假设第一页中最后一个产品 ID 是 2)是
SET ROWCOUNT 2 SELECT * FROM PRODUCT WHERER ID>2
这很简单,但是对于排序原因,如果我们想按价格排序,等式是
SET ROWCOUNT 2
SELECT * FROM Product WHERE ID>@lastProductID and Price = @lastSortByID
UNION ALL
SELECT * FROM Product WHERE Price > @lastSortByID ORDER BY Price, ID
或者,如果您愿意,可以使用 OR
而不是 SQL 中的 UNION ALL
。
SET ROWCOUNT 2
SELECT * FROM Product WHERE (ID>@lastProductID and Price = @lastSortByID)
OR (Price > @lastSortByID) ORDER BY Price, ID
对于第一页,通过应用等式(假设 -1 是价格列的不可能值)
SET ROWCOUNT 2
SELECT * FROM Product WHERE ID>0 and Price = -1
UNION ALL
SELECT * FROM Product WHERE Price > -1 ORDER BY Price, ID
根据该表,第一个 union
连接中没有记录,第二个 union
连接中有两条记录。第一页中的最后一个项目 ID 为 4,价格为 2(上表中的第二条记录),因此我们将这两个值放入下一页的 SQL 语句中,通过应用第二页的等式。
SET ROWCOUNT 2
SELECT * FROM Product WHERE ID>4 and Price = 2
UNION ALL
SELECT * FROM Product WHERE Price > 2 ORDER BY Price, ID
第一个 union
连接将给出 1 条记录,第二个也将给出 1 条记录。第一条记录将给出价格 2 和 ID 5(上表中的第三条记录),第二条记录将给出价格 3 和 ID 1(上表中的第四条记录)。
就是这样。这种机制存在局限性。排序依据的列不能为 null。这是可以解释的。空列无法使用比较运算符进行比较。您不能像这样编写 SQL "WHERE Price = NULL
"。 如果您正在处理可为空的列,则必须将 SQL 更改为更复杂的形式,我将不在此处进行解释。 我还认为任何可搜索的列都不应该为 null,否则,您会自找麻烦。
此机制在客户端很复杂,因为您必须跟踪最后一个排序依据的列值和最后一个唯一列值的视图状态。我花了很多时间编写客户端代码。 我想说明的一个特殊情况是,当用户正在浏览最后一页中的最后一个项目,并且最后一页仅包含一个项目时。 突然,管理员删除了该项目,并且用户再次刷新该页面,则会生成错误。 这些类型的错误也必须处理。
参考
历史
我不是一个非常优秀的开发人员,如果我在文章中犯了一些错误,请纠正。
谢谢。