sql server累计求和函数_SQL基础--SQL高级功能

95d3b0f8a7b72f518fe1ab399d36648c.png

一.窗口函数有什么用?

在日常工作中,经常会遇到需要在每组内排名,比如下面的业务需求:

排名问题:每个部门按业绩来排名
topN问题:找出每个部门排名前N的员工进行奖励

面对这类需求,就需要使用sql的高级功能窗口函数了。

二.什么是窗口函数?

窗口函数,也叫OLAP函数(Online Anallytical Processing,联机分析处理),可以对数据库数据进行实时分析处理。

窗口函数的基本语法如下:

‹窗口函数› 

语法中‹窗口函数›的位置,可以放以下两种函数:

1) 专用窗口函数,包括后面要讲到的rank, dense_rank, row_number等专用窗口函数。

2) 聚合函数,如sum. avg, count, max, min等

因为窗口函数是对where或者group by子句处理后的结果进行操作,所以窗口函数原则上只能写在select子句中

接下来,就结合实例,给大家介绍几种窗口函数的用法。

【经典排名问题】专用窗口函数rank

例如下图,是班级表中的内容

525e4ff7f332998cb88617d3f0021739.png

如果我们想在每个班级内按成绩排名,得到下面的结果。

315118556a9bfb5bf80aff78bb620bc3.png

得到上面结果的sql语句代码如下:

select 

我们来解释下这个sql语句里的select子句。

要求是“每个班级内按成绩排名”,这句话可以分为两部分:

1)每个班级内:按班级分组

partition by用来对表分组。在这个例子中,所以我们指定了按“班级”分组(partition by 班级)

2)按成绩排名

order by子句的功能是对分组后的结果进行排序,默认是按照升序(asc)排列。在本例中(order by 成绩 desc)是按成绩这一列排序,加了desc关键词表示降序排列。

通过下图,我们就可以理解partiition by(分组)和order by(在组内排序)的作用了。

78006821ca0bc114c6ff625fc1c0df81.png

窗口函数具备了我们之前学过的group by子句分组的功能和order by子句排序的功能。那么,为什么还要用窗口函数呢?

这是因为,group by分组汇总后改变了表的行数,一行只有一个类别。而partiition by和rank函数不会减少原表中的行数。例如下面统计每个班级的人数。

15e7e0735704ac2573c952f685c31f90.png

那么为什么叫“窗口”函数呢?这是因为partition by分组后的结果称为“窗口”,这里的窗口不是我们家里的门窗,而是表示“范围”的意思。

简单来说,窗口函数有以下功能:

1)同时具有分组和排序的功能

2)不减少原表的行数

3)语法如下:

‹窗口函数› 

三.其他窗口函数

专用窗口函数rank, dense_rank, row_number有什么区别呢?

举个例子,就能清楚了

select 

6a05c199af9ca2b6d9c94e19aec74648.png

从上面的结果可以看出:

  • rank函数:这个例子中是5位,5位,5位,8位,也就是如果有并列名次的行,会占用下一名次的位置。
  • dense_rank函数:这个例子中是5位,5位,5位,6位,也就是如果有并列名次的行,不占用下一名次的位置。
  • row_number函数:这个例子中是5位,6位,7位,8位,也就是不考虑并列名次的情况。

最后,需要强调的一点是:在上述的这三个专用窗口函数中,函数后面的括号不需要任何参数,保持()空着就可以。

topN问题

每组最大的N条记录

现有“成绩表”,记录了每个学生各科的成绩。表内容如下。问题:查找每个学生成绩最高的2个科目

7c91fbf47781a051074743cbcc15e5e0.png

【解题思路】

  1. 看到“每个”了,肯定是要进行分组,因为是每个学生,所以这里按姓名分组
  2. 按姓名分组后,把成绩降序排列,取最前面两个
  3. 因为不能减少原行数,所以用窗口函数进行分组,并且为了不受并列成绩影响,使用row_number专用窗口函数

【解体步骤】

步骤一:按姓名分组(partiotion by 姓名)、并按成绩降序排列(order by 成绩 desc),套入窗口函数的语法

select 

运行结果如下

73060b05823da8d2a53450f274035a23.png

步骤二:如上表黄色框内的数据,每个同学成绩最好的2个科目,就是要求的解。

那么一下就会想到只要提取出“ranking”值小于等于2的数据就可以了。因此,只需要在上一步的slq语句里加入条件字句where就可以了,注意这样是错误的!!!

一定要注意命令的运行顺序,运行到”where ranking › 2”的时候,因为select字句还没有被执行,因此select中的“ranking”列还没有出现,从而导致报错。

因此,在这里用子查询,也就是把第一步得到查询结果作为一个新的表,sql语句如下:

select 

得到结果:

bce9d7668cad665bab49a073e6de3113.png

【如何在每个组里比较?】

还用上个例子中的表,查找单科成绩高于该科目平均成绩的学生名单?

【解题思路】

  1. 看到“每个”,就要分组。
  2. 使用聚合窗口函数(求平均值avg),将每门课的平均成绩求出以后,然后找出大于比平均成绩的数据。
  3. 因为要用原值和平均值比较,因此要求分组后不能减少表的行数,所以用partition by分组。

【解题步骤】

第1步,聚合函数avg()作为窗口函数,将每一科目成绩的平均值求出。sql语句如下:

select 

结果如下

454f5596c2f9276c02f67110e6b8604f.png

第2步,如上表,按科目分组后各科目的平均分已经计算出,那么,是不是只需要在上一步的slq语句里加入条件字句where就可以了?这里再次注意命令的执行顺序!

和上个例子一样用子查询,也就是把第一步得到查询结果作为一个新的表,sql语句如下:

select 

运行结果如下:

778a45324972744718c2c5e571bfb912.png

四.聚合函数

聚和窗口函数和上面提到的专用窗口函数用法完全相同,只需要把聚合函数写在窗口函数的位置即可,但是函数后面括号里面不能为空,需要指定聚合的列名。

以下面的命令为例

select 

我单独用sum运算过程进行说明:

3e06373042f58961010b6ff3daf6f6f0.png

如上图,聚合函数sum在窗口函数中,是对自身记录、及位于自身记录以上的数据进行求和的结果。比如0004号,在使用sum窗口函数后的结果,是对0001,0002,0003,0004号的成绩求和,若是0005号,则结果是0001号~0005号成绩的求和,以此类推。

不仅是sum求和,平均、计数、最大最小值,也是同理,都是针对自身记录、以及自身记录之上的所有数据进行计算。

如果想要知道所有人成绩的总和、平均等聚合结果,看最后一行即可。

这样使用窗口函数有什么用呢?

聚合函数作为窗口函数,可以在每一行的数据里直观的看到,截止到本行数据,统计数据是多少(最大值、最小值等)。同时可以看出每一行数据,对整体统计数据的影响。

五.窗口函数的移动平均

这里我们直接用聚合函数avg的窗口函数举例说明:

select 

rows和preceding这两个关键字,是“之前~行”的意思。上面的句子中,是之前2行。也就是得到的结果是自身记录及前2行的平均。

例如:学号0004学生的current_avg,是自己和前2位同学的平均,即0002,0003,0004三位同学成绩的平均,其他数据的情况也一样,下图非常直观的可以看到计算过程:

51e6f087370ec6ee8b928c72f2a75841.png

每一行得到的结果,都是当前行和前面2行的平均(共3行)。想要计算当前行与前n行(共n+1行)的平均时,只要调整rows…preceding中间的数字即可。

这里需要注意:在移动平均中,被选出的数据构成一个“框架”,例如,刚才例子中的0002、0003、0004行数据,就是一个“框架”。

这样使用窗口函数有什么用呢?

由于这里可以通过preceding关键字调整作用范围,在以下场景中非常适用:

在公司业绩名单排名中,可以通过移动平均,直观地查看到与相邻名次业绩的平均、求和等统计数据。

六.总结

6e47dc8a9654af88ec7f5d1b5a89e06c.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/329969.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(转)【SpringMvc】如何使用form发送PUT和DELETE请求

转自: https://blog.csdn.net/cockroach02/article/details/82194126https://blog.csdn.net/cockroach02/article/details/82194126 一、当前现状 浏览器使用form提交信息的时候只支持GET和POST,如果需要在浏览器上使用PUT和DELETE请求方式的话&#…

leetcode初级算法4.只出现一次的数字

leetcode初级算法4.只出现一次的数字 仅为个人刷题记录&#xff0c;不提供解题思路 题解与收获 我的解法&#xff1a; public static int singleNumber(int[] nums) {if(nums.length 1){return nums[0];}Arrays.sort(nums);int slow 0;int fast 1;while(fast < nums.…

集合总结(Collection)

转载自 集合总结(Collection) 最近项目上线完&#xff0c;闲来无事&#xff0c;整理了关于集合相关对比&#xff0c;具体详见以下几点&#xff1a;1.ArrayList和Vector区别&#xff1a;这两个类都实现了List接口(List接口继承了Collection接口)&#xff0c;他们都是有序集合&am…

springboot接收浏览器发送delete请求( method not allowed 405解决方法)

【README】 浏览器使用form提交信息的时候只支持GET和POST&#xff0c;如果需要在浏览器上使用PUT和DELETE请求方式的话&#xff0c;只能使用欺骗的方式了&#xff0c;SpringMvc提供了HiddenHttpMethodFilter类来提供支持&#xff1b; 【1】前端 1&#xff09;list.html <…

tensorflow图形检测_社交距离检测器——Tensorflow检测模型设计

在隔离期间&#xff0c;我花时间在github上探索Tensorflow的大量预训练模型。这样做时&#xff0c;我偶然发现了一个包含25 个带有性能和速度指标的预训练对象检测模型的存储库。拥有一些计算机视觉知识并给出了实际的背景知识&#xff0c;我认为使用其中之一来构建社交隔离应用…

leetcode初级算法4.两个数组的交集 II

leetcode初级算法4.两个数组的交集 II 仅为个人刷题记录&#xff0c;不提供解题思路 题解与收获 我的解法&#xff1a;&#xff08;总结在代码中&#xff09; public int[] intersect(int[] nums1, int[] nums2) {//为空则返回if(nums1 null || nums2 null){return null;…

Java NIO:Buffer、Channel 和 Selector

转载自 Java NIO&#xff1a;Buffer、Channel 和 Selector本文将介绍 Java NIO 中三大组件 Buffer、Channel、Selector 的使用。 本来要一起介绍非阻塞 IO 和 JDK7 的异步 IO 的&#xff0c;不过因为之前的文章真的太长了&#xff0c;有点影响读者阅读&#xff0c;所以这里将它…

(转)使用IDEA将普通MAVEN项目转为WEB项目

转自&#xff1a; 使用IDEA将普通MAVEN项目转为WEB项目_yun0000000的博客-CSDN博客使用IDEA将普通MAVEN项目转为WEB项目https://blog.csdn.net/yun0000000/article/details/70664944 1、file--project Structure--,然后点“”号&#xff0c;,若没有war包&#xff0c;可修改mav…

python创建文件对象_python基础教程:文件读写

在Linux系统中&#xff0c;一切都是文件。但我们通常说的文件是保存在磁盘上的图片、文档、数据、程序等等。而在程序的IO操作中&#xff0c;很多时候就是从磁盘读写文件。本节我们讲解Python中的文件对象如何操作文件。创建文件对象 通过Python内置函数open()可以很容易的创建…

(转)springboot:添加JSP支持

转自&#xff1a; 14.springboot:添加JSP支持 - 简书&#xff08;1&#xff09;创建Maven web project 使用Eclipse新建一个Maven Web Project &#xff0c;项目取名为&#xff1a;spring-boot-jsp &#xff08;2&#xff09;在pom.xm...https://www.jianshu.com/p/4216bbd1e0…

leetcode初级算法5.加一

leetcode初级算法5.加一 仅为个人刷题记录&#xff0c;不提供解题思路 题解与收获 我的解法&#xff1a;&#xff08;总结在代码中&#xff09; public int[] plusOne(int[] digits) {//获取digits长度int length digits.length;//判断条件int count 0;//全是9的情况for …

epoll 浅析以及 nio 中的 Selector

转载自 epoll 浅析以及 nio 中的 Selector首先介绍下epoll的基本原理&#xff0c;网上有很多版本&#xff0c;这里选择一个个人觉得相对清晰的讲解&#xff08;详情见reference&#xff09;&#xff1a;首先我们来定义流的概念&#xff0c;一个流可以是文件&#xff0c;socket&…

转-SpringBoot——使用外置的Tomcat服务器

转自&#xff1a; SpringBoot——使用外置的Tomcat服务器_架构师的小跟班的博客-CSDN博客_springboot使用外置tomcat1 前言2 修改步骤2.1 修改打包方式&#xff08;jar -> war&#xff09;2.2 排除 SprignBoot的Web模块中的Tomcat依赖2.2.1 将嵌入的Tomcat依赖方式改成 pro…

leetcode初级算法6.字符串转整数(atoi)

leetcode初级算法6.字符串转整数(atoi) 仅为个人刷题记录&#xff0c;不提供解题思路 题解与收获 我的解法&#xff1a; public int myAtoi(String s) {//避免魔法值先设spaceString space " ";//如果是空或者是一串空字符串就滚回去&#xff01;if(s null || …

inner join on 加条件和where加条件_SQL学习笔记 - GROUP BY / JOIN / UNION

最近在DataCamp上学习SQL&#xff08;基于PostgreSQL&#xff09;的课程&#xff0c;本文主要记录自己易记混的点&#xff0c;以便日后参考学习&#xff0c;不做原理讲解。GROUP BY&#xff08;分组&#xff09;一般和聚合函数一起使用&#xff0c;包括COUNT()&#xff0c;AVG(…

Selector 实现原理

转载自 Selector 实现原理概述 Selector是NIO中实现I/O多路复用的关键类。Selector实现了通过一个线程管理多个Channel&#xff0c;从而管理多个网络连接的目的。 Channel代表这一个网络连接通道&#xff0c;我们可以将Channel注册到Selector中以实现Selector对其的管理。一个C…

转: 深入浅出-网络七层模型

转自 深入浅出&#xff0d;网络七层模型 - sunsky303 - 博客园引言 今天回顾一下&#xff0d;&#xff0d;网络七层模型&&网络数据包 网络基本概念 OSI模型 OSI 模型(Open System Interconnection model)是一个由国际标准化组织&#https://www.cnblogs.com/sunsky3…

date转timestamp格式_技术分享 | MySQL:timestamp 时区转换导致 CPU %sys 高的问题

作者&#xff1a;高鹏文章末尾有他著作的《深入理解 MySQL 主从原理 32 讲》&#xff0c;深入透彻理解 MySQL 主从&#xff0c;GTID 相关技术知识。本文为学习记录&#xff0c;可能有误请谅解。本文建议PC端观看&#xff0c;效果更佳。这个问题是一个朋友遇到的风云&#xff0c…

2021年最新springcloud配置中心不生效的版本原因

想直接看结论请到最下面&#xff0c;中间是我的纠错细节 实名吐槽一波cloudAlibaba文档。 github上的官方文档明明白白写着&#xff1a; 2.2.X版本适用于Springboot 2.2.X 彳亍&#xff01; 于是我将原本的2.6.0版本改成了SpringBoot 2.2.4Release&#xff0c;然后启动报错&a…

python爬新闻并保存csv_用python爬取内容怎么存入 csv 文件中

小白一个&#xff0c;爬取豆瓣电影250作为练习&#xff0c;想把爬取的内容用csv存储&#xff0c;想存但是不知道怎么自己原来代码拼接在一起。 ps:非伸手党&#xff0c;查阅了官方文档&#xff0c;也做了csv读写的练习&#xff0c;就是拼不到一起&#xff0c;不知道该怎么改。求…