总结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属于关系型数据库. 关系模型 以二维表来描述 ...
随机推荐
- js的一些刷新功能
<a href="javascript:location.replace(location.href);" title="刷新"> </a&g ...
- 管理SSIS 日志
转自:http://www.cnblogs.com/biwork/p/biworklog.html 一直准备写这么一篇有关 SSIS 日志系统的文章,但是发现很难一次写的很完整.因为这篇文章的内容可扩 ...
- 在调试javascript的时候,要常使用alert()
在调试javascript的时候,要常使用alert()会帮助我们定位脚本错误.
- Game of Peace
Time Limit: 4000ms, Special Time Limit:10000ms, Memory Limit:65536KB Total submit users: 20, Accepte ...
- TypeScript完全解读(26课时)_19.其他重要更新
ts3.3升级过来有很多重要的更新 没法归类的更新,在本节课几种讲一下 创建update.ts,然后在index.ts内引入 async和promise es6中增加了promise的支持,能够很好处 ...
- POJ - 2676 Sudoku 数独游戏 dfs神奇的反搜
Sudoku Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smalle ...
- DOM学习笔记(一)DOM树
DOM 定义了访问和操作 HTML 文档的标准方法. HTML 文档中的所有内容都是节点,将 HTML 文档表达为树结构,称为节点树 HTML DOM 树 HTML DOM 是关于如何获取.修改.添加 ...
- kuangbin带你飞 - 合集
[题目列表] 之前有一些做过了的,这次从数论开始?
- 简单介绍Git两种拉取代码的方式
first: 1.通过git clone 命令克隆git库中的项目 注意:通过 git clone方式克隆的代码会在服务器上自动建一个与git库名相同的文件夹,所以有两种思路,第一种就是直接在wwwr ...
- 手把手教你使用ueditor
ueditor的强大功能就不再一一叙述了,我们的目的就是通过使用php与html实现下面的效果 话不多说,上干货 前言:文件都是基于tp5的 1.引入富文本编辑器 将 ueditor 下的文件引入 1 ...