您的位置:首页 > 其它

ROW_NUMBER、RANK、DENSE_RANK的用法(2) 实例说明与对比

2011-03-29 16:00 591 查看
SQLserver2005新增的几个函数,分别是row_number()、rank()、,DENSE_RANK()、ntile()下面以实例分别简单讲解。

1.row_number()
先来点数据,先建个表

SETNOCOUNTON
CREATETABLEPerson(
FirstNameVARCHAR(10),
AgeINT,
GenderCHAR(1))
INSERTINTOPersonVALUES('Ted',23,'M')
INSERTINTOPersonVALUES('John',40,'M')
INSERTINTOPersonVALUES('George',6,'M')
INSERTINTOPersonVALUES('Mary',11,'F')
INSERTINTOPersonVALUES('Sam',17,'M')
INSERTINTOPersonVALUES('Doris',6,'F')
INSERTINTOPersonVALUES('Frank',38,'M')
INSERTINTOPersonVALUES('Larry',5,'M')
INSERTINTOPersonVALUES('Sue',29,'F')
INSERTINTOPersonVALUES('Sherry',11,'F')
INSERTINTOPersonVALUES('Marty',23,'F')直接用例子说明问题:SELECTROW_NUMBER()OVER(ORDERBYAge)AS[RowNumberbyAge],
FirstName,
Age
FROMPerson
出现的数据如下
RowNumberbyAgeFirstNameAge
--------------------------------------------
1Larry5
2Doris6
3George6
4Mary11
5Sherry11
6Sam17
7Ted23
8Marty23
9Sue29
10Frank38
11John40
可以观察到,是根据年龄升序排列了,并且row_number()是给出了序列号了,这个序列号被重命名为RowNumberbyAge,
sqlserver2000对比:
如果在sqlserver2000中实现相对麻烦一些,我们可以利用IDENTITY()函数实现,但IDENTITY()函数只能用在sqlserver2000临时表中,因此需要将数据检索到临时表里。
selectidentity(int,1,1)as[RowNumberbyAge],FirstName,Ageinto#AfromPersonorderbyAge
select*from#A
droptable#a
如果不想按年龄排序,可以这样写
SELECTROW_NUMBER()OVER(ORDERBY(SELECT1))AS[RowNumberbyRecordSet],FirstName,AgeFROMPerson
另外一个例子
SELECTROW_NUMBER()OVER(PARTITIONBYGenderORDERBYAge)AS[PartitionbyGender],FirstName,Age,GenderFROMPerson
这里是按性别划分区间了,同一性别再按年龄来排序,输出结果如下
PartitionbyGenderFirstNameAgeGender
-----------------------------------------------
1Doris6F
2Mary11F
3Sherry11F
4Sue29F
1Larry5M
2George6M
3Sam17M
4Ted23M
5Marty23M
6Frank38M
7John40M

注意,姓名M开始,序号又从1,2,3开始了
2.RANK()函数
先看例子
SELECTRANK()OVER(ORDERBYAge)AS[RankbyAge],FirstName,AgeFROMPerson
输出如下:
[code]RankbyAgeFirstNameAge
-----------------------------------------[/code]
1Larry5
2Doris6
2George6
4Mary11
4Sherry11
6Sam17
7Ted23
7Marty23
9Sue29
10Frank38
11John40
看到了么,同年岭的话,将有相同的顺序,顺序成1,2,2,4了。
sqlserver2000对比:
出现了RANK()函数实在是方便,在sqlserver2000里实现排序并列的问题麻烦很多。
select[RankbyAge]=isnull((selectcount(*)frompersonwhereAge>A.Age),0)+1,FirstName,AgefromPersonAorderby[RankbyAge]
SELECTRANK()OVER(PARTITIONBYGenderORDERBYAge)AS[PartitionbyGender],
FirstName,Age,GenderFROMPerson输出为
PartitionbyGenderFirstNameAgeGender
-----------------------------------------------
1Doris6F
2Mary11F
2Sherry11F
4Sue29F
1Larry5M
2George6M
3Sam17M
4Ted23M
4Marty23M
6Frank38M
7John40M
可以看到,按性别分组了,每个性别分组里,继续是用了rank()函数

3.DENSE_RANK()函数
SELECTDENSE_RANK()OVER(ORDERBYAge)AS[DenseRankbyAge],
FirstName,
Age
FROMPerson

输出结果为:
DenseRankbyAgeFirstNameAge
-----------------------------------------
1Larry5
2Doris6
2George6
3Mary11
3Sherry11
4Sam17
5Ted23
5Marty23
6Sue29
7Frank38
8John40

看到了么,和rank函数区别是,顺序始终是连续的,Doris和George同年,都是排第2位,但之后的mary不象rank函数那样排第4,而是排第3位了

4.ntile()函数
SELECTFirstName,
Age,
NTILE(3)OVER(ORDERBYAge)AS[AgeGroups]
FROMPerson

输出结果:
FirstNameAgeAgeGroups
-----------------------------------------
Larry51
Doris61
George61
Mary111
Sherry112
Sam172
Ted232
Marty232
Sue293
Frank383
John403
这个函数按照ntile(n)中的N,把记录强制分成多少段,11条记录现在分成3段了,lary到mary是第1段,sherry到maty是第2段,sue到john是第3段了。

转:http://blog.csdn.net/htl258/archive/2009/03/20/4006717.aspx感谢作者分享。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: