有没有更好的方法在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
有没有更好的方法,所以我不必添加跳过?
答案 0 :(得分:6)
在SQL 2012中,它非常简单:
SELECT LastName, FirstName
FROM person.Person
WHERE FirstName like '%ad%'
ORDER BY LastName
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;
查看this link以了解其他版本的SQL服务器+性能比较。
答案 1 :(得分: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 :如果最终SELECT
子句中有更多列,此解决方案应该会更好。