SQL⽣成序号的四种⽅式
排名函数是SQL SERVER2005新增的函数。排名函数总共有四种,分别是:row_number、rank、 dense_rank 、ntile。
row_number:顺序⽣成序号。
rank:相同的序值序号相同,但序号会跳号。
dense_rank :相同的序值序号相同,序号顺序递增。
ntile:装桶,把记录分成指的桶数,编序号。
下⾯分别介绍⼀下这四个排名函数的功能及⽤法。在介绍之前假设有⼀个t_table表,表结构与表中的数据如图1所⽰:
图1
其中field1字段的类型是int,field2字段的类型是varchar。
⼀、row_number
row_number函数的⽤途是⾮常⼴泛,这个函数的功能是为查询出来的每⼀⾏记录⽣成⼀个序号。row_number函数的⽤法如下⾯的SQL 语句所⽰:
select row_number() over(order by field1) as row_number,* from t_table
上⾯的SQL语句的查询结果如图2所⽰。
图2
其中row_number列是由row_number函数⽣成的序号列。在使⽤row_number函数是要使⽤over⼦句选择对某⼀列进⾏排序,然后才能⽣成序号。
实际上,row_number函数⽣成序号的基本原理是先使⽤over⼦句中的排序语句对记录进⾏排序,然后
按着这个顺序⽣成序号。over⼦句中的order by⼦句与SQL语句中的order by⼦句没有任何关系,这两处的order by 可以完全不同,如下⾯的SQL语句所⽰:
select row_number() over(order by field2 desc) as row_number,* from t_table order by field1 desc
上⾯的SQL语句的查询结果如图3所⽰。
图3
我们可以使⽤row_number函数来实现查询表中指定范围的记录,⼀般将其应⽤到Web应⽤程序的分页功能上。下⾯的SQL语句可以查询t_table表中第2条和第3条记录:
1. with t_rowtable
2. as
3. (
4.    select row_number() over(order by field1) as row_number,* from t_table
5. )
6. select * from t_rowtable where row_number>1 and row_number < 4 order by field1
上⾯的SQL语句的查询结果如图4所⽰。
图4
另外要注意的是,如果将row_number函数⽤于分页处理,over⼦句中的order by 与排序记录的order by 应相同,否则⽣成的序号可能不是有续的。
⼆、rank
rank函数考虑到了over⼦句中排序字段值相同的情况,为了更容易说明问题,在t_table表中再加⼀条记录,如图5所⽰。
select rank() over(order by field1),* from t_table order by field1
上⾯的SQL语句的查询结果如图6所⽰。
图6
sql语句实现的四种功能三、dense_rank
dense_rank函数的功能与rank函数类似,只是在⽣成序号时是连续的,⽽rank函数⽣成的序号有可能不连续。如上⾯的例⼦中如果使⽤dense_rank函数,第4条记录的序号应该是2,⽽不是4。如下⾯的SQL语句所⽰:
select dense_rank() over(order by field1),* from t_table order by field1
⾯的SQL语句的查询结果如图7所⽰。
图7
四、ntile
ntile函数可以对序号进⾏分组处理。这就相当于将查询出来的记录集放到指定长度的数组中,每⼀个数组元素存放⼀定数量的记录。ntile函数为每条记录⽣成的序号就是这条记录所有的数组元素的索引(从1开始)。也可以将每⼀个分配记录的数组元素称为“桶”。ntile 函数有⼀个参数,⽤来指定桶数。下⾯的SQL语句使⽤ntile函数对t_table表进⾏了装桶处理:
select ntile(4) over(order by field1) as bucket,* from t_table
上⾯的SQL语句的查询结果如所⽰。
由于t_table表的记录总数是6,⽽上⾯的SQL语句中的ntile函数指定了桶数为4。