Welcome to EMC Consulting Blogs Sign in | Join | Help

SSIS Junkie

Once upon a time this blog was a hive of activity. Now however its pretty lifeless as you can probably tell so if are pining for more of the same you can find me over at http://sqlblog.com/blogs/jamie_thomson. I look forward to seeing you there!

ROW_NUMBER() Function

There is a new feature in SQL Server 2005 that is akin to the ROWNUM function in Oracle which I am going to blog about here. I'm sure alot of people reading will already know about this function and its syntax/behaviour but this post may still serve as a useful reference. I'm mainly writing this for my colleagues at Conchango that won't have come across it yet.

I am going to demo using the sample database AdventureWorks that comes with SQL Server 2005 so the first thing you'll want to do is install the sample DB and issue
USE AdventureWorks

There is a view in this database called Sales.vSalesPerson (note the Schema.ObjectName qualification rather than Owner.ObjectName that existing SQL Server users will be used to). This view provides, for each sales person, SalesYTD, SalesLastYear and the sales person's country region.

Object Explorer


A simple:

select CountryRegionName,FirstName,LastName,SalesYTD,SalesLastYear
from Sales.vSalesPerson

returns the following data:
Result Set for select CountryRegionName, FirstName, LastName, SalesYTD, SalesLastYear from Sales.vSalesPerson


But lets suppose we want to rank the salespeople based on their SalesYTD. This is where the ROW_NUMBER function comes into play. The syntax (as given in BOL) is:


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


< OVER_CLAUSE > :: =
    OVER ( [ PARTITION BY < value_expression > , ... [ n ] ]
           )

So let's rewrite our SQL statement:

select row_number() over (order by SalesYTD asc) as rownum, CountryRegionName, FirstName, LastName, SalesYTD, SalesLastYear from Sales.vSalesPerson


and see what that gives us:
 

Result set for select row_number() over (order by SalesYTD asc) as rownum, CountryRegionName, FirstName, LastName, SalesYTD, SalesLastYear from Sales.vSalesPerson

As you can see 2 things have happened:
1) The results have been ordered in ascending order according to SalesYTD
2) There is a new column ("rownum") indicating the order within the dataset.
Very useful!

But wait. There's more!!
As you can see above the syntax allows for the provision of a PARTITION BY clause. This enables you to first group the rows according to a given attribute and then rank them within that group.
Let's add this to our SQL statement:

select row_number() over (partition by CountryRegionName order by SalesYTD asc) as rownum, CountryRegionName, FirstName, LastName, SalesYTD, SalesLastYear
from Sales.vSalesPerson


This time we get:
Result set for select row_number() over (partition by CountryRegionName order by SalesYTD asc) as rownum, CountryRegionName, FirstName, LastName, SalesYTD, SalesLastYear from Sales.vSalesPerson

You can see that the records have been grouped according to CountryRegionName prior to applying the value from ROW_NUMBER(). Straightaway we can see which are our best sales people in each region.

Of course, you can include multiple expressions in the PARTITION BY clause to enable you to apply groupings and sub-groupings to your data.

This is just a taste of one of the new features. Hopefully this post will be of use to someone!

-Jamie

 

Note: This information is based on SQL Server 2005 Beta 2!

Published 16 February 2005 21:11 by jamie.thomson
Filed under:

Comments

 

TrackBack said:

sql.ru
March 22, 2005 17:50
 

adam machanic :: sql server programming said:

&amp;nbsp;I'm not sure how many times over the last several years I've seen the
same tired article titles......
August 4, 2005 20:08
 

adam machanic :: data manipulation for fun and profit said:

&amp;nbsp;I'm not sure how many times over the last several years I've seen the
same tired article titles......
August 4, 2005 20:09
 

adam machanic :: sql server programming said:

&amp;nbsp;I'm not sure how many times over the last several years I've seen the
same tired article titles......
August 4, 2005 20:42
 

adam machanic :: sql server programming said:

I'm not sure how many times over the last several years I've seen the
same tired article titles... &quot;Climbing...
August 5, 2005 05:16
 

adam machanic :: sql server programming said:

I'm not sure how many times over the last several years I've seen the
same tired article titles... &quot;Climbing...
August 5, 2005 05:17
 

gideon said:

Dear Sir,
I AM new to SQL 2005.When i execute the ROW_NUMBER() query i have the following ERROR

Query:

SELECT ROW_NUMBER()OVER (ORDER BY QuestionID) AS 'Row Number',Answer,AnswerID,QuestionNumber,FROM dbo.Questions;

ERROR:
Msg 195, Level 15, State 10, Line 2
'ROW_NUMBER' is not a recognized function name.


Kindly give your Suggesion ASAP.

Gideon

gidyaxn@gmail.com  
April 12, 2006 06:26
 

gideon said:

Dear Sir,
I AM new to SQL 2005.When i execute the ROW_NUMBER() query i have the following ERROR

Query:

SELECT ROW_NUMBER()OVER (ORDER BY QuestionID) AS 'Row Number',Answer,AnswerID,QuestionNumber,FROM dbo.Questions;

ERROR:
Msg 195, Level 15, State 10, Line 2
'ROW_NUMBER' is not a recognized function name.


Kindly give your Suggesion ASAP.

Gideon

gidyaxn@gmail.com  
April 12, 2006 06:27
 

jamie.thomson said:

Your syntax is wrong. Do not put apostrophes around the alias.

You also have a rogue comma just below FROM that should not be there.

-Jamie
April 12, 2006 07:36
 

Adam Machanic said:

Originally posted here.

I'm not sure how many times over the last several years I've seen the
same...
July 13, 2006 05:48
 

SSIS Junkie said:

With the advent of SQL Server 2005, Microsoft provided three new T-SQL windowing functions that will

September 12, 2006 14:37
 

Adam Machanic said:

Originally posted here . I'm not sure how many times over the last several years I've seen the same tired

January 8, 2007 19:29
 

Pallav said:

Good refrence specialy PARTITION BY clause is new to me Thanks...

April 24, 2007 13:46
 

Richard Morgan Jr. said:

Jamie and Gideon

I believe the real trouble is that Gideon is executing that code on a SQL 2000 platform, where the row_number() function is currently not implemented.  The apostrophes around the alias are perfectly fine (Gideon could use 'apos', [brack], or "quot", it just depends on his office conventions), but the Comma preceding the "FROM" is truly in error.  Running this on a 2005 Server the code should look like...

[code]

SELECT ROW_NUMBER() OVER (ORDER BY QuestionID) AS 'RowNumber'

           ,Answer

           ,AnswerID

           ,QuestionNumber

FROM dbo.Questions;

[/code]

May 9, 2007 21:08
 

Suhas T said:

This is the function used in the SQL Server 2005, But if I need the replacement for this finction in the SQL server 2000 the what will be solution?

May 29, 2007 07:27
 

son said:

<a href=http://www.yahoo.com >good</a> article

July 10, 2007 10:11
 

BRIAN said:

This is really very helpful. Thanks guys.

But this is just one of the new feature of 2005 with a very good example. Do you guys have any other new feature like this with a good example??

If so please post the link..

August 23, 2007 15:32
 

jamie.thomson said:

Brian,

Most of my blog is devoted to SSIS, a new feature in SQL Server 2005. 286 posts in fact (at time of writing): http://blogs.conchango.com/jamiethomson/archive/tags/SSIS/default.aspx

-Jamie

August 23, 2007 16:24
 

Li Li said:

Thank you! I found your explanation very comprehensive.

September 18, 2007 12:01
 

jason.brown said:

Jamie - this is exactly what I have been looking for - your example is clear and I will be visiting your blog often. You are appreciated!!!

October 10, 2007 18:23
 

russ said:

This is much more useful than the SQL BOL.  Extremely helpful.  Saved me from writing a bunch of subqueries to do the same thing.

December 6, 2007 23:25
 

Yogesh(ybaraiya@gmail.com) said:

I want code of ROW_NUMBER() for SQL Server 2000.

January 9, 2008 06:22
 

Marco Retamales (marco.retamales@hotmail.com) said:

This code simule the ROW_NUMBER() function in SQL 2000.

Regards , Marco

----

use tempdb

go

if object_id('tempdb.dbo.#t_1') is not null

drop table #t_1

if object_id('tempdb.dbo.#t_2') is not null

drop table #t_2

create table #t_1

(

id int identity(1, 1) not for replication not null primary key,

bid varchar(10)

)

create index bid on #t_1 (bid)

insert into #t_1

select bid

from

(

select 'A' as bid

union all select 'B'

union all select 'B'

union all select 'C'

union all select 'D'

union all select 'D'

union all select 'D'

) as t_1

-- creamos una tabla temporal donde determinaremos

-- los difernentes códigos de bid

create table #t_2

(

id int identity(1,1) not for replication not null primary key,

bid varchar(10),

rows_count int default (0)

)

create index bid on #t_2 (bid)

-- ejemplificamos con una tabla donde hay 4 bids

insert into #t_2

select bid, count(*) from #t_1

group by bid

select #t_1.bid, #t_1.id, (#t_1.id - (select min(id) from #t_1 t where t.bid = #t_1.bid)) + 1 [row_number]

from #t_1 inner join #t_2

on #t_1.bid = #t_2.bid

February 20, 2008 03:12
 

Mani said:

Thank you, esp. for the partition clause

March 28, 2008 01:24
 

niyy said:

HI,

I want to ask you a question: how to get all indexs belongs to a table.

Thanks.

my email: sina_qq@hotmail.com

March 28, 2008 02:31
 

Aarti said:

hello sir

SELECT row_number() OVER(ORDER BY ManufacturerName)AS 'Row',mfgAcronym, ManufacturerName,mfgShow,mfgWebsite FROM tblMfg

and i am getting following error: 'row_number' is not a recognized function name.

Please help me out .its urgent,

my emailid is  aarti.3882@hotmail.com

May 12, 2008 12:33
 

José said:

Hi,

I'm Using SQL Server Management Studio 2005, and I'm trying to use the funciton row_Number(), but can´t use this cause I'm getting the error:

error: 'row_number' is not a recognized function name.

This function existes in SQL Server Management Studio 2005 ???

Thx.

May 15, 2008 13:31
 

jamie.thomson said:

In exists in SQL Server 2005. The fact that you are using SSMS is irrelevant, you need to be connected to a SQL Server 2005 instance.

-Jamie

May 15, 2008 13:34
 

José said:

Hi,

Thx Jamie.thomson for ur reply. I asked here what is the Instance and :'(.

Is SQL SErver 2000.

I must found other way to get rown number, without using a tem table :S

Thx

May 15, 2008 13:41
 

Tips on Using a Stored Procedure for Searching « Cobble My Wall said:

May 22, 2008 18:33
 

Smitha R Mangalore said:

I am new to Database programming. Could you tell me how to fetch in between records (110 to 130) from SQL Server 2005. I need TSQL statement for the same

August 14, 2008 10:37
 

jamie.thomson said:

select *

from tablename

where columnname between 110 and 130

August 14, 2008 14:47
 

Manoj said:

It is nice article with good samples

September 4, 2008 13:24
New Comments to this post are disabled

This Blog

Syndication

Powered by Community Server (Personal Edition), by Telligent Systems