总结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, ScoreFROM 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, ScoreFROM 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, ScoreFROM 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, ScoreFROM 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属于关系型数据库. 关系模型 以二维表来描述 ...
随机推荐
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">详解
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- JavaWeb学习——获取类路径下的资源
对于JavaWeb而言,获取类路径下的资源,就是获取classes目录下的资源. 获取资源的方式有两种,利用Class或ClassLoader. Class类的getResourceAsStream( ...
- C++中拷贝构造函数
C++中拷贝构造函数 1.什么是拷贝构造函数: 拷贝构造函数嘛,当然就是拷贝和构造了.(其实很多名字,只要静下心来想一想,就真的是顾名思义呀)拷贝又称复制,因此拷贝构造函数又称复制构造函数.百度百科上 ...
- P5137 polynomial(分治)
传送门 神仙--这题有毒-- 一直在那里考虑没有逆元怎么办然后考虑解exgcd巴拉巴拉 最后只好看题解了 而且这题龟速乘都不行--得用代码里那种叫人半懂不懂的方式取模-- //minamoto #in ...
- IT兄弟连 JavaWeb教程 Servlet会话跟踪 Session优缺点
● 数据存储在服务器,安全. ● session能保存Object类型数据,也就是说能存储任意数据. ● 可存储的数据大小,理论上是无限制的. ● 因为数据存储在服务器端,当用户比较多时,会占 ...
- IT兄弟连 JavaWeb教程 Servlet会话跟踪 设置Session存活时长
方式一:修改所有的session默认时长,修改tomcat目录下的conf文件夹下的web.xml文件. <session-config> <session-timeout>希 ...
- 在mpvue框架中使用Vant WeappUI组件库的注意事项
1如何引入组件库 有两种方法 1 npm下载 2 下载代码,下面介绍第二种方法. 在gitHub上, 链接如下 https://github.com/youzan/vant-weapp 首先在自己项目 ...
- PAT 1040有几个PAT
原题:https://pintia.cn/problem-sets/994805260223102976/problems/994805282389999616 1040 有几个PAT (25 分) ...
- 存储-InfluxDB
1 TSDB influxDB是一个time series时间序列数据库. 在监控系统的开发中,大体分为采集-存储-可视化三个大类.监控指标有很显著的时间特征数据,一般采用TSDB存储. 在TSDB中 ...
- __slots__,__doc__,__module__,__class__.__call__
__slots__ 1.__slots__是什么:是一个类变量,变量值可以是列表,元祖,或者可迭代对象,也可以是一个字符串(意味着所有实例只有一个数据属性)2.引子:使用点来访问属性本质就是在访问类或 ...