如何从表中选择一部分行?

时间:2014-03-08 16:38:32

标签: sql sql-server select rows

我需要从位置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和排序让我觉得性能非常糟糕。

这样做的正确方法是什么?

2 个答案:

答案 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;