34 out of 51 rated this helpful - Rate this topic

ROW_NUMBER (Transact-SQL)

Returns the sequential number of a row within a partition of a result set, starting at 1 for the first row in each partition.

Topic link iconTransact-SQL Syntax Conventions


ROW_NUMBER ()     OVER ( [ <partition_by_clause> ] <order_by_clause> )
<partition_by_clause>

Divides the result set produced by the FROM clause into partitions to which the ROW_NUMBER function is applied. For the PARTITION BY syntax, see OVER Clause (Transact-SQL).

<order_by_clause>

Determines the order in which the ROW_NUMBER value is assigned to the rows in a partition. For more information, see ORDER BY Clause (Transact-SQL). An integer cannot represent a column when the <order_by_clause> is used in a ranking function.

The ORDER BY clause determines the sequence in which the rows are assigned their unique ROW_NUMBER within a specified partition.

A. Returning the row number for salespeople

The following example returns the ROW_NUMBER for the salespeople in AdventureWorks based on the year-to-date sales.

SELECT FirstName, LastName, ROW_NUMBER() OVER(ORDER BY SalesYTD DESC) AS 'Row Number', SalesYTD, PostalCode 

FROM Sales.vSalesPerson

WHERE TerritoryName IS NOT NULL AND SalesYTD <> 0;

B. Returning a subset of rows

The following example returns rows with numbers 50 to 60 inclusive in the order of the OrderDate.

USE AdventureWorks;
GO
WITH OrderedOrders AS
(
    SELECT SalesOrderID, OrderDate,
    ROW_NUMBER() OVER (ORDER BY OrderDate) AS 'RowNumber'
    FROM Sales.SalesOrderHeader 
) 
SELECT * 
FROM OrderedOrders 
WHERE RowNumber BETWEEN 50 AND 60;

C. Using ROW_NUMBER() with PARTITION

The following example shows using the ROW_NUMBER function with the PARTITION BY argument.

SELECT FirstName, LastName, ROW_NUMBER() OVER(PARTITION BY PostalCode ORDER BY SalesYTD DESC) AS 'Row Number', SalesYTD, PostalCode 
FROM Sales.vSalesPerson
WHERE TerritoryName IS NOT NULL AND SalesYTD <> 0;
Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ
Answer: How about the ACTUAL rownum?!?
$0This also works, for returning raw row number:$0 $0DECLARE @tmp int = 0$0 SELECT ROW_NUMBER() OVER (ORDER BY @tmp) AS RowIndex, * FROM AnyTable$0
Answer: How about the ACTUAL rownum?!?
There is no such thing is a raw rownumber without any form of PK. There is no fixed sequence, since the data is stored through hash indexes, leading to only non-determant recovery unless there's an ordered index (like a PK).

Any fetch of data without such an ordered index would yield a different ordered result each time (aside of short term caching perhaps). Adding rownumbers to such datasets will not allow for any reliable back-referencing to the datarows. You'll simply need a PK for that, ordered unique index, or (default) order clause over distinct values.

----------

edit: Actually, a post by Ghanaya is correct - since RAND() returns the same number for each row, ordering by that will return the actual row count.

Answer: How about the ACTUAL rownum?!?
You can use Rand() function in order by clause as shown below

Select *, ROW_NUMBER() OVER (ORDER BY rand()) AS RowNum from emp5

This returns rows in actual order and is fast even if there is no PK column

How about the ACTUAL rownum?!?
You know, the one from the physical medium that the db is on... I don't want to order by anything (for argument's sake, suppose there's no PK column), i want the raw data, and the raw row numbering...
  • 6/26/2009
  • Cbx
  • 6/26/2009
  • Cbx