我需要从位置Y开始从表中选择X行;特定列用于对表进行排序。
此查询几乎有效:
DECLARE @Index int
DECLARE @Count int
SELECT * FROM
(
SELECT TOP (@Count) * FROM
(
SELECT TOP (@Index + @Count) * FROM Table
ORDER BY Table.OrderColumn ASC
) AS T1
ORDER BY T1.OrderColumn DESC
) AS T2
ORDER BY T2.OrderColumn ASC
但是,如果表中没有足够的行(例如,表有120行,我想从位置100开始有50行),则此查询只会忽略起始位置并返回最后X行。
此外,使用三个级别的SELECT和排序让我觉得性能非常糟糕。
这样做的正确方法是什么?
答案 0 :(得分:1)
这是可能有效的变体
DECLARE @Index int = 5403
DECLARE @Count int = 1000
SELECT * FROM
(
SELECT TOP (@Index + @Count) *,
ROW_NUMBER() over (order by OrderColumn) as Sequence
FROM MyTable
ORDER BY MyTable.OrderColumn ASC
) as T
WHERE Sequence BETWEEN @Index and @Index + @Count - 1
ORDER BY OrderColumn
派生表(嵌套查询)不应该损害性能。 SQL Server将针对它进行优化。虽然它取决于真实查询的外观。
答案 1 :(得分:0)
如果使用SQL 2012 OFFSET子句可能很方便,下面提供了一个基于AdventureWorks的示例: -
DECLARE @Index int = 100 DECLARE @Count int = 50
SELECT SalesOrderID, OrderDate, CustomerID, SalesPersonID
FROM Sales.SalesOrderHeader
ORDER BY OrderDate, SalesOrderID
OFFSET @Index ROWS FETCH NEXT @Count ROWS ONLY;
如果是SQL2008,使用CTE的Windows函数会很有帮助,基于AdventureWorks的示例: -
DECLARE @Index int = 100
DECLARE @Count int = 50
;WITH C AS
(
SELECT ROW_NUMBER() OVER( ORDER BY OrderDate,SalesOrderID ) AS rownum,
SalesOrderID, OrderDate, CustomerID, SalesPersonID
FROM Sales.SalesOrderHeader
)
SELECT SalesOrderID, OrderDate, CustomerID, SalesPersonID
FROM C
WHERE rownum BETWEEN @Index + 1 AND @Index + @Count
ORDER BY rownum;