`
sjrhero
  • 浏览: 83938 次
  • 性别: Icon_minigender_1
  • 来自: 河南省
社区版块
存档分类
最新评论

SQL Server2005中四个排名函数

阅读更多

排名函数是SQL Server2005新加的功能。在SQL Server2005中有如下四个排名函数:

1. row_number

2. rank

3. dense_rank

4. ntile    
下面分别介绍一下这四个排名函数的功能及用法。在介绍之前假设有一个t_table表,表结构与表中的数据如图1所示:

01

 

 

 

 

 

 


             图1

其中field1字段的类型是intfield2字段的类型是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所示。

03

 

 

 

 

 

 

 

 

 

 


图3

我们可以使用row_number函数来实现查询表中指定范围的记录,一般将其应用到Web应用程序的分页功能上。下面的SQL语句可以查询t_table表中第2条和第3条记录:

 

with t_rowtable
as
(
    select row_number() over(order by field1) as row_number,* from t_table
)
select * from t_rowtable where row_number>1 and row_number < 4 order by field1

上面的SQL语句的查询结果如图4所示。

04

 

 

 

 

 

 

 

 

 

 

 

图4 

    上面的SQL语句使用了CTE,关于CTE的介绍将读者参阅《SQL Server2005杂谈(1):使用公用表表达式(CTE)简化嵌套SQL》
    另外要注意的是,如果将row_number函数用于分页处理,over子句中的order by 与排序记录的order by 应相同,否则生成的序号可能不是有续的。

    当然,不使用row_number函数也可以实现查询指定范围的记录,就是比较麻烦。一般的方法是使用颠倒Top来实现,例如,查询t_table表中第2条和第3条记录,可以先查出前3条记录,然后将查询出来的这三条记录按倒序排序,再取前2条记录,最后再将查出来的这2条记录再按倒序排序,就是最终结果。SQL语句如下:

 

select * from (select top 2 * from( select top 3 * from t_table order by field1) a order by field1 desc) b order by field1

上面的SQL语句查询出来的结果如图5所示。

05

 

 

 

 

 

 

 

 

 

 

 

图5

这个查询结果除了没有序号列row_number,其他的与图4所示的查询结果完全一样。

 

二、rank

     rank函数考虑到了over子句中排序字段值相同的情况,为了更容易说明问题,在t_table表中再加一条记录,如图6所示。 

06

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

图6

     在图6所示的记录中后三条记录的field1字段值是相同的。如果使用rank函数来生成序号,这3条记录的序号是相同的,而第4条记录会根据当前的记录 数生成序号,后面的记录依此类推,也就是说,在这个例子中,第4条记录的序号是4,而不是2。rank函数的使用方法与row_number函数完全相 同,SQL语句如下:

 

select rank() over(order by field1),* from t_table order by field1

上面的SQL语句的查询结果如图7所示。

07

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

图7

三、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语句的查询结果如图8所示。

08 

 

 

 

 

 

 

 

 

 

 

 

 

 

图8

读者可以比较图7和图8所示的查询结果有什么不同。

四、ntile
     ntile函数可以对序号进行分组处理。这就相当于将查询出来的记录集放到指定长度的数组中,每一个数组元素存放一定数量的记录。ntile函数为每条记 录生成的序号就是这条记录所有的数组元素的索引(从1开始)。也可以将每一个分配记录的数组元素称为“桶”。ntile函数有一个参数,用来指定桶数。下 面的SQL语句使用ntile函数对t_table表进行了装桶处理:

 

select ntile(4) over(order by field1) as bucket,* from t_table

 

上面的SQL语句的查询结果如图9所示。

09

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

图9

   由于t_table表的记录总数是6,而上面的SQL语句中的ntile函数指定了桶数为4

    也许有的读者会问这么一个问题,SQL Server2005怎么来决定某一桶应该放多少记录呢?可能t_table表中的记录数有些少,那么我们假设t_table表中有59条记录,而桶数是5,那么每一桶应放多少记录呢?

    实际上通过两个约定就可以产生一个算法来决定哪一个桶应放多少记录,这两个约定如下:

1. 编号小的桶放的记录不能小于编号大的桶。也就是说,第1捅中的记录数只能大于等于第2桶及以后的各桶中的记录。

2. 所有桶中的记录要么都相同,要么从某一个记录较少的桶开始后面所有捅的记录数都与该桶的记录数相同。也就是说,如果有个桶,前三桶的记录数都是10,而第4捅的记录数是6,那么第5桶和第6桶的记录数也必须是6

    根据上面的两个约定,可以得出如下的算法: 

 

// mod表示取余,div表示取整 
    if(记录总数 mod 桶数 == 0)
    {
        recordCount = 记录总数 div 桶数;
        将每桶的记录数都设为recordCount
    } 
    else
    {
        recordCount1 = 记录总数 div 桶数 + 1;
        int n = 1;  //  n表示桶中记录数为recordCount1的最大桶数
        m = recordCount1 * n;
        while(((记录总数 - m)  mod  (桶数 -  n))  != 0 )
        {
            n++;
            m = recordCount1 * n;
        } 
        recordCount2 = (记录总数 - m) div  (桶数 - n);
        将前n个桶的记录数设为recordCount1
        将n + 1个至后面所有桶的记录数设为recordCount2
    }

     根据上面的算法,如果记录总数为59,桶数为5,则前4个桶的记录数都是12,最后一个桶的记录数是11

    如果记录总数为53,桶数为5,则前3个桶的记录数为11,后2个桶的记录数为10

    就拿本例来说,记录总数为6,桶数为4,则会算出recordCount1的值为2,在结束while循环后,会算出recordCount2的值是1,因此,前2个桶的记录是2,后2个桶的记录是1

以上内容来自:http://www.cnblogs.com/nokiaguy/archive/2009/02/05/1384860.html

这次主要是用了Row_Number()函数进行分页。感觉这位朋友写的不错。希望转载的注明上面这个链接。

分享到:
评论

相关推荐

    [sql server]SQL Server2005杂谈(3):四个排名函数的比较.doc

    SQL Server2005杂谈(3):四个排名函数的比较 SQL Server2005杂谈(3):四个排名函数的比较

    SQL2005 四个排名函数(row_number、rank、dense_rank和ntile)的比较

    排名函数是SQL Server2005新加的功能。在SQL Server2005中有如下四个排名函数row_number、rank、dense_rank和ntile,需要的朋友可以参考下。

    Microsoft SQL Server 2005技术内幕: T-SQ程序设计.pdf

    该书解释并比较了SQL Server 2000和SQL Server 2005在数据库开发相关问题上的解决方案,深入讨论了SQL Server 2005中新增的T-SQL编程特性,包含了大量的代码示例、表示例和逻辑难题以帮助数据库开发人员和管理员理解...

    PHP连接SQL Server2005

    1.安装SQL server 2005(这个是废话了)。关键是下一步 2.下载phpstudy2010版,点击下载即可。之后安装(必须是2010版,2011版本无相关文件) 3.打开安装目录,在文件中找到:ntwdblib.dll,将其复制到系统目录:...

    Microsoft SQL Server 2005 Express Edition SP3

    Microsoft SQL Server 2005 Express Edition (SQL Server Express) 是一个免费且易于使用的 SQL Server 2005 版本,它替换了 Microsoft Desktop Engine (MSDE)。与 Microsoft Visual Studio 2005 集成之后,SQL ...

    收集整理的SQL Server自定义函数

    11.取汉字首字母的两个函数 20 12.根据身份证得到生日函数 23 13.根据身份证计算性别函数 24 14.将身份证的15位号码升级为18位 25 15.通过身份证获得户籍 27 16.多个数据项的字符串取指定位置字符 28 17.中缀算术转...

    SQL SERVER 34进制转10进制函数

    一般常见为36进制转10进制,但为了区分26个字母中O和I与阿拉伯数字0和1相似,所以特殊情况会用34进制转10进制( 三十四进制转十进制 )的换算。目的是排除26个字母中O和I,24个字母+10个阿拉伯数字=34。...

    SQL Server 2008 商业智能完美解决方案(3)

    利用Microsoft SQL Server 2008实现灵活的商业智能解决方案使用Microsoft 完善的BI工具构建B0解决方案的必备指南,使用SQLServer 2008设计、开发和部署更有效的数据集成、报表、分析解决方案所需的权威操作指南。...

    深度对比Oracle与SQL Server

    比如说一个做SQL Server开収人员在要写Oracle存储过程的时候可能会先去找那些内置的函数然后比较它们之间不同点,她也可能会去比较发量声明以及错误处理的异同。 本系列文章中我将尝试对Microsoft SQL Server和...

    SQL Server 2005基础知识详细整理

    3.SQL Server 2005中包含master、model、msdb、tempdb四个系统数据库。 4.使用T-SQL语句创建数据库:CREATE DATABASE [ApressFinacial] ON PRIMARY ( NAME = N’ApressFinacial’, FILENAME = N’I:\Program Files\...

    《SQL Server数据库管理与开发》PPT

    第四部分,讲解自定义函数、存储过程和触发器,游标 及事务,数据库访问的安全性;第五部分,讲解数据库管理的备份恢复、导入导出与分离 附加,代理与复制;第六部分,给出了一套数据库应用系统的完整的案例及其源...

    SQL Server 2008商业智能完美解决方案 1/3

    利用Microsoft SQL Server 2008实现灵活的商业智能解决方案使用Microsoft 完善的BI工具构建B0解决方案的必备指南,使用SQLServer 2008设计、开发和部署更有效的数据集成、报表、分析解决方案所需的权威操作指南。...

    SQL函数

    SQL SERVER 的函数 1.字符串函数 长度与分析用 datalength(Char_expr) 返回字符串包含字符数,但不包含后面的空格 substring(expression,start,length) 不多说了,取子串 right(char_expr,int_expr...

    SQL Server 2008数据库设计与实现

    本书深入浅出地介绍了目前世界上最受欢迎的数据库管理系统之一——SQL Server。全书共分三个部分:第一部分阐释了数据库的基本概念,讲解了数据库建模语言;第二部分展示了从概念建模到在SQL Server 2008上真正实现...

    SQL_Sever数据库常用语句大全.zip

    round函数保留指定位数小数点(指定位数后四舍五入) sign函数判断正数负数和零 sqrt平方根函数 convert转换数据类型函数 CURRENT_USER返回当前用户名字 datalength返回双字符串字节长度(一个中文2个字节) Host_...

    sqlserver四舍五入使用round函数及cast和convert函数

     今天和测试沟通一个百分比计算方式时遇到一个问题, 我在存储过程里用到了强转CAST(32.678 AS DECIMAL(5,1)) 我认为该方式只会保留一位小数,我给测试的回复是我并没有用到四舍五入函数,数据也没有四舍五入,而...

    SQL Server 2008商业智能完美解决方案 3/3

    利用Microsoft SQL Server 2008实现灵活的商业智能解决方案使用Microsoft 完善的BI工具构建B0解决方案的必备指南,使用SQLServer 2008设计、开发和部署更有效的数据集成、报表、分析解决方案所需的权威操作指南。...

    SQL Server 2008商业智能完美解决方案 2/3

    利用Microsoft SQL Server 2008实现灵活的商业智能解决方案使用Microsoft 完善的BI工具构建B0解决方案的必备指南,使用SQLServer 2008设计、开发和部署更有效的数据集成、报表、分析解决方案所需的权威操作指南。...

    C#防SQL注入代码的三种方法

    对于网站的安全性,是每个... 四:屏蔽SQL,javascript等注入(很是主要的),对于每个文件写是不太可能的。所以要找到对所有文件起作用的办法。我在网上收集了以下3种方法  C#防SQL注入方法一  在Web.config文件中

Global site tag (gtag.js) - Google Analytics