0

有没有更好的方法在 SQL Server 中进行分页?

例如,我必须使用以下技术将 @skip 添加到 @take:

;WITH tmp_cte AS (
 SELECT ROW_NUMBER() OVER (ORDER BY LastName) AS RowNumber,
        LastName, 
        FirstName
   FROM person.Person
  WHERE FirstName like '%ad%'
)
SELECT * 
FROM tmp_cte 
WHERE RowNumber > @skip --10 
AND RowNumber <= @Take--20

有没有更好的方法让我不必添加跳过来服用?

4

2 回答 2

6

在 SQL 2012 中,它非常简单:

SELECT LastName, FirstName
  FROM person.Person
 WHERE FirstName like '%ad%'
 ORDER BY LastName
 OFFSET 10 ROWS 
 FETCH NEXT 10 ROWS ONLY;

查看 此链接 以了解其他版本的 SQL 服务器 + 性能比较。

于 2013-09-21T07:30:39.963 回答
0

如果 Person.Person 表上有一个唯一索引(例如,PersonID列上有一个唯一索引并且该索引是聚集的 - 例如,如果您有一个聚集的 PK),则可能会有更好的解决方案。在这种情况下,上面的查询可以这样重写:

;WITH tmp_cte AS (
    SELECT ROW_NUMBER() OVER (ORDER BY LastName) AS RowNumber, PersonID
    FROM person.Person
    WHERE FirstName like '%ad%'
)
SELECT ...
FROM Person.Person p
WHERE p.PersonID IN -- PersonID is the key of this UNIQUE INDEX
(
SELECT PersonID FROM tmp_cte 
WHERE RowNumber > @skip 10 AND RowNumber <= @Take--20
)

或者

DECLARE @Rows TABLE (ID INT PRIMARY KEY);
;WITH tmp_cte AS (
    SELECT ROW_NUMBER() OVER (ORDER BY LastName) AS RowNumber, PersonID
    FROM person.Person
    WHERE FirstName like '%ad%'
)
INSERT @Rows (ID)
SELECT PersonID FROM tmp_cte 
WHERE RowNumber > @skip 10 AND RowNumber <= @Take--20

SELECT ...
FROM Person.Person p
WHERE p.PersonID IN (SELECT ID FROM @Rows); -- PersonID is the key of this UNIQUE INDEX

注意#1:在这种特殊情况下,或上的索引(FirstName, LastName)(LastName, FirstName) 可能有用。

注意 #2:如果您在 finalSELECT子句中有更多列,则此解决方案应该会执行得更好。

于 2013-09-21T07:44:48.567 回答