iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >MySQL:开窗函数
  • 626
分享到

MySQL:开窗函数

mysql数据库 2023-09-03 07:09:46 626人浏览 安东尼
摘要

当查询条件需要用到复杂子查询时,聚合函数操作起来非常麻烦,因此使用开窗函数能够轻松实现。 注意:在oracle中称为分析函数。            在Mysql中称为开窗函数,使用于mysql8.0以上版本,sql sever、Hive、

当查询条件需要用到复杂子查询时,聚合函数操作起来非常麻烦,因此使用开窗函数能够轻松实现。

注意:在oracle中称为分析函数。

           在Mysql中称为开窗函数,使用于mysql8.0以上版本,sql sever、Hive、Oracle等。

1 开窗函数

开窗函数:为将要被操作的行的集合定义一个窗口,它对一组值进行操作,不需要使用GROUP BY子句对数据进行分组,能够在同一行中同时返回基础行的列和聚合列。

语法:函数 + over(partition by <分组用列> order by <排序用列>)

over() 按所有行进行分组

over(partition by xxx)按xxx分组的所有行进行分组

over(partition by xxx order by aaa)按列xxx分组,按列aaa排序

over(order by aaa) 按aaa列排序

括号中的两个关键词partition by 和order by可以只出现一个。

开窗函数表示对数据集按照分组用列进行分区,并且对每个分区按照函数聚合计算,最终将计算结果按照排序用列排序后返回到该行。

无论何种能力,窗口函数都不会影响数据行数,而是将计算平摊在每一行。

1.1 开窗函数分类

名称描述
cume_dist()计算一组值中一个值的累积分布
dense_rank()根据该order by子句为分区中的每一行分配一个等级。它将相同的等级分配给具有相等值的行。如果两行或更多行具有相同的排名,则排名值序列中将没有间隙
first_value()返回相对于窗口框架第一行的指定表达式的值
lag()返回分区中当前行之前的第N行的值。如果不存在前一行,则返回NULL
last_value()返回相对于窗口框架中最后一行的指定表达式的值
lead()返回分区中当前行之后的第N行的值。如果不存在后续行,则返回NULL
nth_value()从窗口框架的第N行返回参数的值
ntile()将每个窗口分区的行分配到指定数量的排名组中
percent_rank()计算分区域结果集中行的百分数等级
rank()与dense_rank()函数相似,不同之处在于当两行或更多行具有相同的等级时,等级值序列中存在间隙
row_number()为分区中的每一行分配一个顺序整数

按照函数功能不同,MySQL支出的开窗函数分为如下几类:

  • 序号函数:row_number() / rank() / dense_rank()
  • 分布函数:percent_rank() / cume_dist()
  • 前后函数:lag() / lead()
  • 头尾函数:first_value() / last_value()
  • 其他函数 :nth_value() / nfile()

2 排序开窗函数和聚合开窗函数

2.1 排序开窗函数

  • row_number(行号)
  • rank(排名)
  • dense_rank(密集排名)
  • ntile(分组排名)

例1 先对所有数据进行排序

select s.sid,s1.sname,s1.gender,c.cname,s.num,   row_number() over (partition by c.cname order by num desc) as row_number排名,   rank() over (partition by c.cname order by num desc) as rank排名,   dense_rank() over (partition by c.cname order by num desc) as dense_rank排名,   ntile(6) over (partition by c.cname order by num desc) as ntile排名    from score s   join student s1 on s.student_id = s1.sid   left join course c on s.course_id = c.cid

结果如下:

 row_number

根据课程进行分组,然后对每组内的成绩进行降序排序

又上图可知row_number对于同组内的相同成绩并没有做特殊处理,而仅仅是生成连续的序号。row_number常用于按照某列生成连续序号。

rank

rank函数就是对查询出来的记录进行排名。

与row_number函数不同的是,rank函数考虑到了over子句中排序字段值相同的情况,over子句中排序字段值相同的序号是一样的,后面字段值不相同的序号将跳过相同的排名号排下一个,也就是相关行之前的排名数加一,通过上面的例子我们也可以看出,rank考虑到值相同情况,并且它的排名存在跳跃性。

dense_rank

密集排名,在考虑了值相同时,排名也相同,但是序号不跳跃,紧跟上一个序号。

例如题目中体育成绩有2位同学(张三和刘三)并列第一,如果使用rank排名 ,那钢蛋就是第三名,而如果采用dense_rank 那钢蛋就是第二名,这个很容易理解吧。

ntile

ntile会先根据你的分组依据,本题中是课程名称,然后把每个组的总记录数进行按照你给的ntile()里的数字进行,这个数字就是桶数,相当于是把体育课程总共12条记录,尽量等划分成5桶,然后按照num的排序等级划分,每个桶两条记录,也就是112233445566的排序结果了,很显然,这个排序结果的数字大小只能用于桶与桶之间,而桶内部记录虽然序号相同,但是num不一定相同。

例如:统计各科成绩前三 

select * from (select s.sid,s1.sname,s1.gender,c.cname,s.num,dense_rank() over (partition by c.cname order by num desc) as dense_rank排名 from score sjoin student s1 on s.student_id = s1.sidleft join course c on s.course_id = c.cid) as ewhere dense_rank排名 <= 3;

2.2 聚合开窗函数

函数名如果是聚合函数,则称为聚合开窗函数

语法:聚合函数(列) over(partition by 列 order by 列)

常见的聚合函数有:sum()、count()、average()、max()、min()

计算每个学生的及格科目数

select student_id,count(sid) from  score where num>= 60 group by student_id;

通过普通的聚合函数分组计算后,数据表结构发生了变化,它会根据分组进行显示,并且,如果你是根据学生ID分组,那你查询的字段应该也是学生ID,不然会影响到分组结果所对应的数值,例如现在查询条件在添加一个Sid

select sid,student_id,count(sid) from  score where num>= 60 group by student_id;

 

sid的数据并没有实际意义,因为数据表已经根据分组发生了变化。

执行结果

select sid,student_id,count(sid) over(PARTITION by student_id order by student_id) 及格数   from score where num>= 60;

 

 总结:开窗函数不会修改源数据表的结果,也是在表的最后一列添加想要的结果。

实例数据

CREATE TABLE class (  cid int(11) NOT NULL AUTO_INCREMENT,  caption varchar(32) NOT NULL,  PRIMARY KEY (cid)) ENGINE=InnoDB CHARSET=utf8;INSERT INTO class VALUES(1, '三年二班'), (2, '三年三班'), (3, '一年二班'), (4, '二年九班');CREATE TABLE teacher(  tid int(11) NOT NULL AUTO_INCREMENT,  tname varchar(32) NOT NULL,  PRIMARY KEY (tid)) ENGINE=InnoDB DEFAULT CHARSET=utf8;INSERT INTO teacher VALUES(1, '张磊老师'), (2, '李平老师'), (3, '刘海燕老师'), (4, '朱云海老师'), (5, '李杰老师');CREATE TABLE course(  cid int(11) NOT NULL AUTO_INCREMENT,  cname varchar(32) NOT NULL,  teacher_id int(11) NOT NULL,  PRIMARY KEY (cid),  KEY fk_course_teacher (teacher_id),  CONSTRaiNT fk_course_teacher FOREIGN KEY (teacher_id) REFERENCES teacher (tid)) ENGINE=InnoDB DEFAULT CHARSET=utf8;INSERT INTO course VALUES(1, '生物', 1), (2, '物理', 2), (3, '体育', 3), (4, '美术', 2);CREATE TABLE student(  sid int(11) NOT NULL AUTO_INCREMENT,  gender char(1) NOT NULL,  class_id int(11) NOT NULL,  sname varchar(32) NOT NULL,  PRIMARY KEY (sid),  KEY fk_class (class_id),  CONSTRAINT fk_class FOREIGN KEY (class_id) REFERENCES class (cid)) ENGINE=InnoDB DEFAULT CHARSET=utf8;INSERT INTO student VALUES(1, '男', 1, '理解'), (2, '女', 1, '钢蛋'), (3, '男', 1, '张三'), (4, '男', 1, '张一'), (5, '女', 1, '张二'), (6, '男', 1, '张四'), (7, '女', 2, '铁锤'), (8, '男', 2, '李三'), (9, '男', 2, '李一'), (10, '女', 2, '李二'), (11, '男', 2, '李四'), (12, '女', 3, '如花'), (13, '男', 3, '刘三'), (14, '男', 3, '刘一'), (15, '女', 3, '刘二'), (16, '男', 3, '刘四');CREATE TABLE score (  sid int(11) NOT NULL AUTO_INCREMENT,  student_id int(11) NOT NULL,  course_id int(11) NOT NULL,  num int(11) NOT NULL,  PRIMARY KEY (sid),  KEY fk_score_student (student_id),  KEY fk_score_course (course_id),  CONSTRAINT fk_score_course FOREIGN KEY (course_id) REFERENCES course (cid),  CONSTRAINT fk_score_student FOREIGN KEY (student_id) REFERENCES student(sid)) ENGINE=InnoDB DEFAULT CHARSET=utf8;INSERT INTO score VALUES(1, 1, 1, 10),(2, 1, 2, 9),(5, 1, 4, 66),(6, 2, 1, 8),(8, 2, 3, 68),(9, 2, 4, 99),(10, 3, 1, 77),(11, 3, 2, 66),(12, 3, 3, 87),(13, 3, 4, 99),(14, 4, 1, 79),(15, 4, 2, 11),(16, 4, 3, 67),(17, 4, 4, 100),(18, 5, 1, 79),(19, 5, 2, 11),(20, 5, 3, 67),(21, 5, 4, 100),(22, 6, 1, 9),(23, 6, 2, 100),(24, 6, 3, 67),(25, 6, 4, 100),(26, 7, 1, 9),(27, 7, 2, 100),(28, 7, 3, 67),(29, 7, 4, 88),(30, 8, 1, 9),(31, 8, 2, 100),(32, 8, 3, 67),(33, 8, 4, 88),(34, 9, 1, 91),(35, 9, 2, 88),(36, 9, 3, 67),(37, 9, 4, 22),(38, 10, 1, 90),(39, 10, 2, 77),(40, 10, 3, 43),(41, 10, 4, 87),(42, 11, 1, 90),(43, 11, 2, 77),(44, 11, 3, 43),(45, 11, 4, 87),(46, 12, 1, 90),(47, 12, 2, 77),(48, 12, 3, 43),(49, 12, 4, 87),(52, 13, 3, 87);

来源地址:https://blog.csdn.net/weixin_48719464/article/details/130197380

您可能感兴趣的文档:

--结束END--

本文标题: MySQL:开窗函数

本文链接: https://www.lsjlt.com/news/391789.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • MySQL:开窗函数
    当查询条件需要用到复杂子查询时,聚合函数操作起来非常麻烦,因此使用开窗函数能够轻松实现。 注意:在Oracle中称为分析函数。            在MySQL中称为开窗函数,使用于MySQL8.0以上版本,sql sever、hive、...
    99+
    2023-09-03
    mysql 数据库
  • MySQL 开窗函数
    目录(1)开窗函数的定义(2)开窗函数的实际应用场景结合order by关键词和limit关键词是可以解决很多的topN问题,比如从二手房数据集中查询出某个地区的最贵的10套房,从电...
    99+
    2024-04-02
  • 【Mysql系列】LAG与LEAD开窗函数
    💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,...
    99+
    2023-12-22
    mysql 数据库
  • MySQL中如何使用开窗函数
    这篇文章主要介绍了MySQL中如何使用开窗函数,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。(1)开窗函数的定义开窗函数也叫OLAP函数(Online Analytical ...
    99+
    2023-06-29
  • Mysql 窗口函数
    一, MySQl 8.0 窗口函数 窗口函数适用场景: 对分组统计结果中的每一条记录进行计算的场景下, 使用窗口函数更好, 注意, 是每一条!! 因为MySQL的普通聚合函数的结果(如 group...
    99+
    2023-09-17
    scala spark java
  • MySQL窗口函数(MySQL Window Functions)
           MySQL从8.0开始支持窗口函数(Window Functions),因其经常被用在数据分析的场景,窗口函数也被称为分析函数(Analytic Functions)。 目录 一、窗口函数概念 二、基础语法 ...
    99+
    2023-09-01
    数据库
  • MySQL8.0数据库开窗函数
    简介       数据库开窗函数是一种在SQL中使用的函数,它可以用来对结果集中的数据进行分组和排序,以便更好地分析和处理数据。开窗函数与聚合函数不同,它不会将多行数据聚合成一行,而是保留每一行数据,并对其进行分组和排序。 常见的开窗函...
    99+
    2023-09-13
    数据库 mysql
  • ORACLE数据库 开窗函数
    开窗函数 2.1开窗函数的定义及语法 开窗函数(又名:分析函数,窗口函数,OLAP函数) 聚合函数:将数据按照一定的规则分组,统一分析各组的某项情况,每个分组返回一行结果 开窗函数:将数据按照一定的规则分组,统一分析各组的某项情况,每行数据...
    99+
    2023-09-02
    数据库 oracle python
  • MYSQL窗口函数(Rows & Range)——滑动窗口函数用法
    语法介绍 窗口函数语法: over (partition by order by rows/range子句 ) 可以放以下两种函数: 1) 专用窗口函数,包括后面要讲到的rank, den...
    99+
    2023-09-03
    mysql 数据库
  • MySQL窗口函数 PARTITION BY()函数介绍
    前期数据准备 # 创建数据库create database if not exists shopping charset utf8;# 选择数据库use shopping;# 创建产品表create ...
    99+
    2023-09-12
    mysql sql 数据库
  • mysql窗口函数有哪些
    本篇文章为大家展示了mysql窗口函数有哪些,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1、说明可以用来实现一些新的查询方式。窗口函数像SUM()、COUNT()这样的集合函数,但不是将多行查询结...
    99+
    2023-06-15
  • Oracle分析函数之开窗函数over()详解
    分析函数是什么? 分析函数是Oracle专门用于 解决复杂报表统计需求 的功能强大的函数, 它可以在数据中进行分组然后计算基于组的某种统计值 ,并且每一组的每一行都可以返回一个统计值。 ...
    99+
    2024-04-02
  • SQL中的开窗函数是什么
    本篇内容主要讲解“SQL中的开窗函数是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“SQL中的开窗函数是什么”吧!OVER的定义OVER用于为行定义一个窗口...
    99+
    2024-04-02
  • MySQL 8.0窗口函数怎么运行
    今天就跟大家聊聊有关MySQL 8.0窗口函数怎么运行,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。# ROW_NUMBER() ...
    99+
    2024-04-02
  • MySQL窗口函数的具体使用
    目录一、什么是窗口函数1、怎么理解窗口?2、什么是窗口函数二、窗口函数用法1、序号函数:row_number() / rank() / dense_rank()2、分布函数:...
    99+
    2024-04-02
  • 窗口函数OVER(PARTITION BY)详细用法——语法+函数+开窗范围ROWS和RANGE
    目录 一、函数写法 二、开窗的窗口范围ROWS与RANGE 1.范围限定用法 2.ROWS和RANGE的区别 (1) ROWS按行数限定 (2) RANGE按数据范围限定         order by 数字               ...
    99+
    2023-09-02
    数据库 mysql sql
  • SparkSQL开窗函数分析使用示例
    目录聚合函数和开窗函数开窗函数聚合开窗函数排序开窗函数开窗函数能在每行的最后一行都显示聚合函数的结果,所以聚合函数可以用作开窗函数 聚合函数和开窗函数 聚合函数是将多行变成一行,如果...
    99+
    2023-01-28
    SparkSQL开窗函数 SparkSQL窗口函数
  • MySQL窗口函数实现榜单排名
    目录rank()dense_rank()row_number()rank()函数的模拟实现dense_rank()的模拟实现row_number的模拟实现总结相信大家在日常的开发中经常会碰到榜单类的活动需求,通常在榜单中...
    99+
    2023-04-11
    MySQL 榜单排名 MySQL 排名
  • SQL窗口函数之取值窗口函数的使用
    目录案例分析1.环比分析2.同比分析3.复合增长率4.不同产品最高和最低销售额示例表和脚本关于窗口函数的基础,请看文章SQL窗口函数 取值窗口函数可以用于返回窗口内指定位置的数据行。...
    99+
    2024-04-02
  • SQL窗口函数之排名窗口函数的使用
    目录案例分析案例使用的示例表1.环比分析2.同比分析3.复合增长率4.不同产品最高和最低销售额示例表和脚本关于窗口函数的基础,请看文章SQL窗口函数 取值窗口函数可以用于返回窗口内指...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作