简体   繁体   English

使用一个select语句返回特定范围之间的行

[英]Return rows between a specific range, with one select statement

I'm looking to some expresion like this (using SQL Server 2008) 我正在寻找这样的表达(使用SQL Server 2008)

SELECT TOP 10 columName FROM tableName

But instead of that I need the values between 10 and 20. And I wonder if there is a way of doing it using only one SELECT statement. 但不是我需要10到20之间的值。我想知道是否有一种方法只使用一个SELECT语句。

For example this is useless: 例如,这是无用的:

SELECT columName FROM
(SELECT ROW_NUMBER() OVER(ORDER BY someId) AS RowNum, * FROM tableName) AS alias
WHERE RowNum BETWEEN 10 AND 20

Because the select inside brackets is already returning all the results, and I'm looking to avoid that, due to performance. 因为select括号内部已经返回了所有结果,并且由于性能的原因,我希望避免这种情况。

There is a trick with row_number that does not involve sorting all the rows. row_number有一个技巧,不涉及对所有行进行排序。

Try this: 尝试这个:

SELECT columName
FROM (SELECT ROW_NUMBER() OVER(ORDER BY (select NULL as noorder)) AS RowNum, *
      FROM tableName
     ) as alias
WHERE RowNum BETWEEN 10 AND 20

You cannot use a constant in the order by . 您不能在order by使用常量。 However, you can use an expression that evaluates to a constant. 但是,您可以使用计算结果为常量的表达式。 SQL Server recognizes this and just returns the rows as encountered, properly enumerated. SQL Server识别出这一点,只返回遇到的行,并正确枚举。

Use SQL Server 2012 to fetch/skip! 使用SQL Server 2012来获取/跳过!

SELECT SalesOrderID, SalesOrderDetailID, ProductID, OrderQty, UnitPrice, LineTotal
FROM AdventureWorks2012.Sales.SalesOrderDetail
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;

There's nothing better than you're describing for older versions of sql server. 没有什么比你描述旧版本的sql server更好了。 Maybe use CTE, but unlikely to make a difference. 也许使用CTE,但不太可能有所作为。

WITH NumberedMyTable AS
(
    SELECT
        Id,
        Value,
        ROW_NUMBER() OVER (ORDER BY Id) AS RowNumber
    FROM
        MyTable
)
SELECT
    Id,
    Value
FROM
    NumberedMyTable
WHERE 
    RowNumber BETWEEN @From AND @To  

or, you can remove top 10 rows and then get next 10 rows, but I double anyone would want to do that. 或者,你可以删除前10行,然后获得接下来的10行,但是我想要做到这一点。

Why do you think SQL Server would evaluate the entire inner query? 为什么您认为SQL Server会评估整个内部查询? Assuming your sort column is indexed, it'll just read the first 20 values. 假设您的排序列已编入索引,它只会读取前20个值。 If you're really nervous you could do this: 如果你真的很紧张,你可以这样做:

Select
  Id 
From (
  Select Top 20 -- note top 20
    Row_Number() Over(Order By Id) As RowNum,
    Id 
  From
    dbo.Test
  Order By
    Id
  ) As alias
Where
  RowNum Between 10 And 20
Order By
  Id

but I'm pretty sure the query plan is the same either way. 但我很确定查询计划是相同的。

(Really) Fixed as per Aaron's comment. (真的)根据Aaron的评论修正了。

http://sqlfiddle.com/#!3/db162/6 http://sqlfiddle.com/#!3/db162/6

One more option 还有一个选择

SELECT TOP(11) columName
FROM dbo.tableName
ORDER BY
CASE WHEN ROW_NUMBER() OVER (ORDER BY someId) BETWEEN 10 AND 20 
     THEN ROW_NUMBER() OVER (ORDER BY someId) ELSE NULL END DESC

You could create a temp table that is ordered the way you want like: 您可以创建一个按您想要的方式排序的临时表:

SELECT ROW_NUMBER() OVER(ORDER BY someId) AS RowNum, * FROM tableName into ##tempTable ... SELECT ROW_NUMBER()OVER(ORD BY someId)AS RowNum,* FROM tableName into ## tempTable ...

That way you have an ordered list of rows. 这样你就有了一个有序的行列表。 and can just query by row number the subsequent times instead of doing the inner query multiple times. 并且可以在后续时间按行号查询,而不是多次执行内部查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM