使用Row_Number()选择行的子集

tes*_*est 4 sql database row-number sql-server-2008-r2

Select id, name, ROW_NUMBER() OVER (ORDER BY id asc) as 'RowNo'
from customers
where RowNo between 50 AND 60
Run Code Online (Sandbox Code Playgroud)

我试图选择50到60之间的行的子集.问题是'RowNo'是无效的列名.

谢谢

使用SQL SERVER 2008 R2

Mic*_*aga 12

将您的查询用作子查询,如下:

select * from (
    Select id, name, ROW_NUMBER() OVER (ORDER BY id asc) as [RowNo]
    from customers
) t
where RowNo between 50 AND 60
Run Code Online (Sandbox Code Playgroud)

您也可以使用CTE但是是否选择一个而不是另一个读取CTE和SubQuery之间的区别?并检查执行计划.

  • 谢谢你!我不知道为什么在 mysql 中只使用 LIMIT 49, 10 时需要执行如此复杂的查询!你能告诉我为什么我们必须写“t”吗? (2认同)
  • @test:因为SQL-Server没有`LIMIT x OFFSET y`,就像MySQL一样.它只有`TOP n`和MySQL的'LIMIT n`相同. (2认同)
  • 但是使用它所拥有的分析函数,比如`ROWN_NUMBER()`和其他函数,你可以做更复杂的事情(在MySQL中真的很难). (2认同)
  • @test`t`是子查询的别名,没有它你会得到一个错误(你可以试试).有关它的更多信息[使用子查询的任何内容附近的语法不正确](http://stackoverflow.com/questions/4997132/sql-server-2008-mgmt-studio-incorrect-syntax-near-anything-using-subquery). (2认同)

mar*_*c_s 5

你需要做这样的事情:

;WITH PaginatingData AS
(
    Select id, name, ROW_NUMBER() OVER (ORDER BY id asc) as 'RowNo'
    from customers
)
SELECT *
FROM PaginatingData
where RowNo between 50 AND 60
Run Code Online (Sandbox Code Playgroud)

使用CTE(公用表表达式 - 一种"内联视图")作为"包装器",以便您RowNo成为有效的列名.

作为展望 - 使用SQL Server 2012,您可以编写如下内容:

SELECT 
    id, name
FROM 
    dbo.customers
ORDER BY
    id
OFFSET 50 ROWS
FETCH NEXT 10 ROWS ONLY
Run Code Online (Sandbox Code Playgroud)

SQL Server 2012将使用符合ANSI SQL标准的符号直接根据ORDER BY子句进行分页.有关更多信息和更多示例,请参阅此博客文章(或其他大量文章).