如何使用ROW_NUMBER()?


174

我想使用ROW_NUMBER()获取...

  1. 得到max(ROW_NUMBER())->或者我想这也将是所有行的计数

我试着做:

SELECT max(ROW_NUMBER() OVER(ORDER BY UserId)) FROM Users

但这似乎没有用...

  1. ROW_NUMBER()使用给定的信息,即 如果我有一个名字,并且想知道名字来自哪一行。

我认为这与我尝试过的#1类似

SELECT ROW_NUMBER() OVER(ORDER BY UserId) From Users WHERE UserName='Joe'

但这也不起作用...

有任何想法吗?

Answers:


150

对于第一个问题,为什么不只是使用?

SELECT COUNT(*) FROM myTable 

得到计数。

对于第二个问题,该行的主键是用于标识特定行的键。不要尝试为此使用行号。


如果您在主查询中返回了Row_Number(),

SELECT ROW_NUMBER() OVER (Order by Id) AS RowNumber, Field1, Field2, Field3
FROM User

然后,当您想返回5行时,可以获取当前行号,并使用以下查询确定当前行为-5的行

SELECT us.Id
FROM (SELECT ROW_NUMBER() OVER (ORDER BY id) AS Row, Id
     FROM User ) us 
WHERE Row = CurrentRow - 5   

在我的情况下,我得到了一个UserId,我想获得一定行数的UserId。如果某行被删除怎么办?在那种情况下,我不能只使用UserId-offset,因为那样我将无法获得正确的记录。

最好使用mytable中的select count(1)选择记录数。如此快捷高效
Sivajith

46

尽管我同意其他人可以使用count()来获取总行数的方法,但这是如何使用的row_count()

  1. 要获取总行数:

    with temp as (
        select row_number() over (order by id) as rownum
        from table_name 
    )
    select max(rownum) from temp
  2. 要获取名称为Matt的行号:

    with temp as (
        select name, row_number() over (order by id) as rownum
        from table_name
    )
    select rownum from temp where name like 'Matt'

您可以进一步使用min(rownum)max(rownum)获取Matt的第一行或最后一行。

这些是的非常简单的实现row_number()。您可以将其用于更复杂的分组。在不使用子查询的情况下,查看我对高级分组的回复


您能否解释一下如何选择用于中的列order by X?换句话说,应该如何X确定?谢谢!
凯文·梅雷迪斯

@KevinMeredith:这order by X是用于确定行分配顺序的顺序ROW_NUMBERS()。请记住,关系数据库中的表尽管有名称,但没有正式的顺序,因此,如果要调用行“ 1”,“ 10”或“ 1337”,则需要先使用ORDER BY子句对它们进行排序是该OVER (ORDER BY X)子句中的内容。
Wtrmute

25

如果您需要返回表的总行数,则可以使用另一种方法 SELECT COUNT(*)语句。

因为SELECT COUNT(*)进行全表扫描以返回行数,所以对于大表可能要花费很长时间。sysindexes在这种情况下,可以改用系统表。有一ROWS列包含数据库中每个表的总行数。您可以使用以下选择语句:

SELECT rows FROM sysindexes WHERE id = OBJECT_ID('table_name') AND indid < 2

这将大大减少查询所花费的时间。


您对全表扫描是正确的,但是请注意,它不一定是聚集索引扫描,因为它可能为此使用非聚集索引
yoel halb 2012年

2
同样,这仅适用于Sql-Server,因为其他RDMBS已优化选择计数
yoel halb 2012年

7

ROW_NUMBER() 对于以1开头的每一行,返回一个唯一的数字。您只需编写以下代码即可轻松使用:

ROW_NUMBER() OVER (ORDER BY 'Column_Name' DESC) as ROW_NUMBER

你可以找到之间的差异Row_number()Rank()Dense_Rank() 在这里


7

您可以使用它来获取具有has子句的第一条记录

SELECT TOP(1) * , ROW_NUMBER() OVER(ORDER BY UserId) AS rownum 
FROM     Users 
WHERE    UserName = 'Joe'
ORDER BY rownum ASC

4
SELECT num, UserName FROM 
 (SELECT UserName, ROW_NUMBER() OVER(ORDER BY UserId) AS num
  From Users) AS numbered
WHERE UserName='Joe'

要枚举所有行-否则,您只是枚举用户名是Joe的行,这不是目标;-)。
Alex Martelli,2009年

1
@Matt:叫我一个学徒;我倾向于使用“派生表”或“匿名视图”代替术语“子选择”。
mechanical_meat

1
@adam,因为我也是学徒-“嵌套选择”会让您更快乐吗?我不喜欢不使用表格或视图等术语TABLEVIEW关键字或关键字的情况 ……但可以SELECT肯定!!)
Alex Martelli,2009年

@Alex:您提出了一个正确的观点。“嵌套选择”对我非常有用:)顺便说一句,我真的很喜欢阅读您添加到评论和答案中的轶事。
Mechanical_meat 2009年

@亚当,谢谢!有时我的答案是非常裸露的代码,如此处所示,但我确实喜欢在有空余时间时充实它们;-)。
Alex Martelli,2009年

4

可能与这里的问题无关。但我发现使用ROW_NUMBER-

SELECT *,
ROW_NUMBER() OVER (ORDER BY (SELECT 100)) AS Any_ID 
FROM #Any_Table


2

如果您绝对要为此使用ROW_NUMBER(而不是count(*)),则可以始终使用:

SELECT TOP 1 ROW_NUMBER() OVER (ORDER BY Id)   
FROM USERS  
ORDER BY ROW_NUMBER() OVER (ORDER BY Id) DESC

2

您可以使用Row_Number限制查询结果。

例:

SELECT * FROM (
    select row_number() OVER (order by createtime desc) AS ROWINDEX,* 
    from TABLENAME ) TB
WHERE TB.ROWINDEX between 0 and 10

-通过上述查询,我​​将从中获得第1页结果TABLENAME


2

需要使用创建虚拟表WITH table AS,这在给定的Query中提到。

通过使用此虚拟表,您可以执行CRUD操作wrt row_number

查询:

WITH table AS
-
(SELECT row_number() OVER(ORDER BY UserId) rn, * FROM Users)
-
SELECT * FROM table WHERE UserName='Joe'
-

您可以使用或在最后一句中使用INSERT,尽管。UPDATEDELETESELECT


0

SQL Row_Number()函数用于对相关记录集中的数据行进行排序并为其分配一个序号。因此,它用于对行进行编号,例如,确定具有最高订单金额的前10行,或确定每个客户的订单金额最高的行,等等。

如果要对数据集进行排序并通过将每行划分为类别来对每一行进行编号,我们可以将Row_Number()与Partition By子句一起使用。例如,对数据集中包含所有订单的每个客户的订单进行排序等。

SELECT
    SalesOrderNumber,
    CustomerId,
    SubTotal,
    ROW_NUMBER() OVER (PARTITION BY CustomerId ORDER BY SubTotal DESC) rn
FROM Sales.SalesOrderHeader

但据我了解,您想计算按列分组的行数。为了可视化需求,如果您想将相关客户的所有订单计数作为除订单信息之外的单独列查看,则可以将COUNT()聚合函数与Partition By子句一起使用

例如,

SELECT
    SalesOrderNumber,
    CustomerId,
    COUNT(*) OVER (PARTITION BY CustomerId) CustomerOrderCount
FROM Sales.SalesOrderHeader

0

该查询:

SELECT ROW_NUMBER() OVER(ORDER BY UserId) From Users WHERE UserName='Joe'

将返回所有行UserName'Joe',除非你有没有UserName='Joe'

它们将按顺序列出,UserID并且该row_number字段将从1开始并递增,但是许多行包含UserName='Joe'

如果对您不起作用,则您的WHERE命令有问题,或者UserID表中没有。检查字段UserID和的拼写UserName

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.