总结SQL Server窗口函数的简单使用
总结SQL Server窗口函数的简单使用
前言:我一直十分喜欢使用SQL Server2005/2008的窗口函数,排名函数ROW_NUMBER()尤甚。今天晚上我在查看SQL Server开发的相关文档,整理收藏夹发现了两篇收藏已久的好文,后知后觉,读后又有点收获,顺便再总结一下。
一、从一个熟悉的示例说起
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
WITH Record AS ( SELECT Row_Number() OVER ( ORDER BY Id DESC ) AS RecordNumber, Id, FirstName, LastName, Height, Weight FROM Person (NOLOCK) ) SELECT RecordNumber, ( SELECT COUNT (0) FROM Record) AS TotalCount, Id, FirstName, LastName, Height, Weight FROM Record WHERE RecordNumber BETWEEN 1 AND 10 |
二、窗口函数
1
2
3
4
5
6
7
8
|
CREATE TABLE [StudentScore]( [Id] [ int ] IDENTITY(1,1) NOT NULL , [StudentId] [ int ] NOT NULL CONSTRAINT [DF_StudentScore_StudentId] DEFAULT ((0)), [ClassId] [ int ] NOT NULL CONSTRAINT [DF_StudentScore_ClassId] DEFAULT ((0)), [CourseId] [ int ] NOT NULL CONSTRAINT [DF_StudentScore_CourseId] DEFAULT ((0)), [Score] [ float ] NOT NULL CONSTRAINT [DF_StudentScore_Score] DEFAULT ((0)), [CreateDate] [datetime] NOT NULL CONSTRAINT [DF_StudentScore_CreateDate] DEFAULT (getdate()) ) ON [ PRIMARY ] |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
--CourseId 2:语文 4:数学 8:英语 --1班学生成绩 INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (1,1,2,85) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (2,1,2,95.5) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (3,1,2,90) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (1,1,4,90) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (2,1,4,98) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (3,1,4,89) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (1,1,8,80) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (2,1,8,75.5) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (3,1,8,77) --2班学生成绩 INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (1,2,2,90) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (2,2,2,77) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (3,2,2,78) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (4,2,2,83) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (1,2,4,98) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (2,2,4,95) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (3,2,4,78) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (4,2,4,100) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (1,2,8,85) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (2,2,8,90) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (3,2,8,86) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (4,2,8,78.5) --3班学生成绩 INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (1,3,2,82) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (2,3,2,78) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (3,3,2,91) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (1,3,4,83) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (2,3,4,78) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (3,3,4,99) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (1,3,8,86) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (2,3,8,78) INSERT INTO StudentScore(StudentId,ClassId,CourseId,Score) VALUES (3,3,8,97) |
窗口函数使用OVER函数实现,OVER函数分带参和不带参两种。其中可选参数PARTITION BY用于将数据按照特定字段分组。
1
2
3
4
5
6
7
8
9
10
11
|
SELECT --Id, --CreateDate, StudentId, ClassId, CourseId, Score, CAST ( AVG (Score) OVER() AS decimal (5,2) ) AS '语文平均分' FROM StudentScore WHERE CourseId=2 |

1
2
3
4
5
6
7
8
9
10
11
|
SELECT Id, CreateDate, StudentId, ClassId, CourseId, Score, CAST ( AVG (Score) OVER(PARTITION BY ClassId ) AS decimal (5,2) ) AS '语文平均分' FROM StudentScore WHERE CourseId=2 |

b、可以在表达式中混合使用基本列和聚合列
二、让人爱不释手的排名函数
1
2
3
4
5
6
7
8
9
10
11
|
SELECT Id, -- CreateDate, ROW_NUMBER() OVER( ORDER BY Score DESC ) AS '序号' , StudentId, ClassId, CourseId, Score FROM StudentScore WHERE CourseId=8 |

1
2
3
4
5
6
7
8
9
10
11
|
SELECT Id, -- CreateDate, RANK() OVER( ORDER BY Score DESC ) AS '序号' , StudentId, ClassId, CourseId, Score FROM StudentScore WHERE CourseId=8 |

b、不同的是,ROW_NUMBER函数为每一个值生成唯一的序号,而RANK函数为相同的值生成相同的序号。
上图中,两个86分的学生对应的序号都是3,而接着排在它们下面的序号直接变成了5。
1
2
3
4
5
6
7
8
9
10
11
|
SELECT Id, -- CreateDate, DENSE_RANK() OVER( ORDER BY Score DESC ) AS '序号' , StudentId, ClassId, CourseId, Score FROM StudentScore WHERE CourseId=8 |

如果分区的行数不能被 integer_expression 整除,则将导致一个成员有两种大小不同的组。按照 OVER 子句指定的顺序,较大的组排在较小的组前面。
1
2
3
4
5
6
7
8
9
10
11
|
SELECT Id, -- CreateDate, NTILE(6) OVER( ORDER BY ClassId DESC ) AS '组编号' , StudentId, ClassId, CourseId, Score FROM StudentScore WHERE CourseId=8 |

总结SQL Server窗口函数的简单使用的更多相关文章
- SQL Server授权购买简单介绍
SQL Server授权购买简单介绍 之前有同事问我,使用盗版序列号的SQL Server到底有没有性能限制,之前本人一直没有深入研究过,后来经过一番资料搜集和查证,汇总成这篇文章 微软的SQL Se ...
- (4.34)sql server窗口函数
关键词:sql server窗口函数,窗口函数,分析函数 如果分析函数不可用,那么可能是版本还不支持 Window Function 包含了 4 个大类.分别是: 1 - Rank Function ...
- SQL Server Profiler的简单使用
SQL Server Profiler可以检测在数据上执行的语句,特别是有的项目不直接使用sql语句,直接使用ORM框架的系统处理数据库的项目,在调试sql语句时,给了很大的帮助. 之前写了使用SQL ...
- SQL Server Service Broker 简单例子 (转)
SQL Server Service Broker服务体系结构 消息类型 — 定义应用程序间交换的消息的名称.还可以选择是否验证消息.约定 — 指定给定会话中的消息方向和消息类型.队列 — 存储消息. ...
- SQL Server Profiler的简单使用(监控mssql)
SQL Server Profiler可以检测在数据上执行的语句,特别是有的项目不直接使用sql语句,直接使用ORM框架的系统处理数据库的项目,在调试sql语句时,给了很大的帮助. 之前写了使用SQL ...
- mySql学习笔记:比sql server书写要简单
在学mySql.总的感觉,mySql与Sql Server差不多,语法都很象,但mySql也许是吸取了SQL SERVER的一些经验,SQL语句书写起来更加简单. 比如说,设置主键.索引,SQL SE ...
- SQL Server窗口函数:ROWS与RANGE
几乎每次我展示SQL Server里的窗口时,人们都非常有兴趣知道,当你定义你的窗口(指定的一组行)时,ROWS与RANGE选项之间的区别.因此在今天的文章里我想给你展示下这些选项的区别,对于你的分析 ...
- C#对于sql server数据库的简单操作
1.在用windows模式登陆sql server 数据库 简历一个student的数据库,然后新建查询: create table student ( id int auto_increment p ...
- SQL SERVER数据库的简单介绍
一.数据库技术的发展 数据库技术是应数据管理任务的需求而产生的,先后经历了人工管理.文件系统.数据库系统等三个阶段. 二.关系型数据库 SQL Server属于关系型数据库. 关系模型 以二维表来描述 ...
随机推荐
- web集群时代
随着业务的不断增加,我们的单台服务器承受不住需求,那么我们就需要对此进行伸缩,有两种维度,一种是纵向的也就是增大该台服务器的硬件,再者就是加新服务器与之前的机器组成集群对外提供服务,我们都知道前者是有 ...
- java:calendar类及一些比较实用的utils(一)
在java编程中经常会用到时间日期的计算.比较.格式化等等操作,刚开始接触Calendar类时,还是在初学习期间,小小白一枚,看着这个好复杂,懒惰心理作祟也就没有怎么去学习,后来在项目中经常用到,索性 ...
- Numbers Exchange
题意: Eugeny有n张卡片,他希望和Nikolay交换一些卡片使得他拥有的奇数数字和偶数数字的卡片数目一样,且所有数字都不同. Nikolay有m张卡片,分别写着1到m.问最少交换几次,能够满足要 ...
- C#读写Access数据库、表格datagridview窗体显示代码实例
C#读写Access数据库.表格datagridview窗体显示代码实例 最近项目中用到C#对于Access数据库表读写.mdb操作,学习了下相关的东西,这里先整理C#对于Access数据库的操作,对 ...
- C#基础:通过委托给任何对象数组进行排序
在日常编写程序的时候,我们需要对一些对象进行排序,比如对int数组进行排序,自定义类数组进行排序,首先我们先讨论对数组进行排序,我们应该对冒泡排序比较熟悉,下面是数组用冒泡排序的方法 for (int ...
- 《剑指offer面试题4》替换空格——实现函数把字符串中每个空格替换成“%20”
思路: 例如把we are happy这个字符串中所有空格替换成"%20",最直接的做法是从头开始扫苗,遇到空格就替换,并且把空格后面的字符都顺序后移.复杂度O(n^2). 重要思 ...
- 5-2 Windows消息队列 (25分)
5-2 Windows消息队列 (25分) 消息队列是Windows系统的基础.对于每个进程,系统维护一个消息队列.如果在进程中有特定事件发生,如点击鼠标.文字改变等,系统将把这个消息加到队列当中 ...
- 小程序隐藏或自定义 scroll-view滚动条
css 隐藏滚动条 ::-webkit-scrollbar { width:; height:; color: transparent; } 自定义滚动条样式 ::-webkit-scrollbar ...
- 跳跃表&hash
汇编刚学跳跃表,发现跳跃表与hash有着数不清的关系 维基百科: 哈希表(哈希映射)是实现关联数组抽象数据类型的数据结构,该结构可以将键映射到值.哈希表使用哈希函数来计算桶或槽阵列的索引,从中可以找到 ...
- SpringBoot | quartz | @DisallowConcurrentExecution
注释放在job类上, 作用: 将该注解加到job类上,告诉Quartz不要并发地执行同一个job定义(这里指特定的job类)的多个实例.