当前位置: 首页 > news >正文

mysql-窗口函数一

目录

一、感受一下分组与窗口函数的区别

二、滑动窗口(子窗口)大小的确认

2.1 分组函数下order by使用

 2.2 窗口子句

2.3 执行流程

三、函数使用

窗口函数需要mysql的版本大于等于8才行,可以先检查一下自己的mysql版本是多少

select version();

准备一下表数据

drop table if exists student;
create table student
(cid    varchar(50),sname  varchar(50),course varchar(50),score  int
) character set utf8mb4;-- 插入两个班级的学生数据(每个学生包含4门课程成绩)
INSERT INTO student (cid, sname, course, score)
VALUES
-- 班级01
('01', '张三', '语文', 85),
('01', '张三', '数学', 92),
('01', '张三', '英语', 78),
('01', '张三', '物理', 88), 
('01', '李四', '语文', 76),
('01', '李四', '数学', 88),
('01', '李四', '英语', 95),
('01', '李四', '化学', 90), 
('01', '王五', '语文', 65),
('01', '王五', '数学', 73),
('01', '王五', '英语', 82),
('01', '王五', '生物', 77), -- 班级02
('02', '赵六', '语文', 90),
('02', '赵六', '数学', 67),
('02', '赵六', '英语', 88),
('02', '赵六', '地理', 85), 
('02', '陈七', '语文', 72),
('02', '陈七', '数学', 85),
('02', '陈七', '英语', 91),
('02', '陈七', '历史', 89), 
('02', '周八', '语文', 68),
('02', '周八', '数学', 79),
('02', '周八', '英语', 84),
('02', '周八', '政治', 83); 

一、感受一下分组与窗口函数的区别

假设现在有一个需求需要统计每个学生的各科总成绩,我们分别使用分组group by 和窗口函数 partion by 来试一下

先来看看group by

select cid, sname, sum(score)
from student
group by sname;

 这里是以每个学生的名字来分组的,显然这里只有六个学生,那么就只会有六行数据

接下来我们看看 partion by的使用

select *,sum(score) over (partition by sname)
from student;

从行来看:可以很明显的感受到,分组group by是先分组在把数据进行压缩,但是窗口函数是保留了并没有对行数进行压缩

从列来看:也是发现一个mysql5.7和mysql8的区别,因为我本机是5.7,在云服务器上面用了mysql8,今天惊奇的发现mysql8,不是分组列,不能被展示,意思就是我只能展示两列,一列是sname(分组列),聚合函数一列

也就是说group by生成的表与原有的表行数和列数都不相同

 

二、滑动窗口(子窗口)大小的确认

2.1 分组函数下order by使用

先说结论,排序只会在当前窗口内进行排序

假设现在有一个需求,需要查询每个同学的各科成绩为降序排列

select sname, course, score, 
row_number() over (partition by sname order by score desc)
from student;

 2.2 窗口子句

窗口子句:控制每一行在可以滑动的子窗口的窗口的大小
起始行:N preceding/unbounded preceding
当前行:current row
终止行:N followding/unbounded preceding

举例:rows between 上边界 and 下边界

#从之前的所有行到当前行
rows between unbounded preceding and current row
#从前面的两行到当前行
rows between 2 preceding and current row
#从当前的所有行到之后的所有行
rows between current row and unbounded following
#从当前行到后面一行
rows between current row and 1 following

注意:

如果排序子句后面缺少窗口子句: 窗口规范默认是:#从之前的所有行到当前行

rows between unbounded preceding and current row

排序子句和窗口子句都缺少:窗口规范就是:分组的窗口大小

rows between unbounded preceding and unbounded following

2.3 执行流程

  1. 先通过partion by 和order by 定义整个分组的大窗口
  2. 通过orws 子句来定义每一行数据的滑动窗口
  3. 对每行的小窗口内的数据执行并生成新的列

三、函数使用

3.1 排序类

在 SQL 中,rank(),dense_rank(),row_number 是窗口函数,它们的 ​​排序依据​​ 完全由 over子句中的 order by 字段决定的!!!

函数重复值处理逻辑示例(分数为 90 的两人)
​ROW_NUMBER()​为每行分配唯一序号,即使值相同也按顺序编号。90 → 1, 90 → 2
​RANK()​相同值分配相同排名,后续排名跳跃。90 → 1, 90 → 1 → 下一行为 3
​DENSE_RANK()​相同值分配相同排名,后续排名连续。90 → 1, 90 → 1 → 下一行为 2

3.2 聚合类

3.3 跨行类


http://www.mrgr.cn/news/100878.html

相关文章:

  • 数据升降级:医疗数据的“时空穿梭“系统工程(分析与架构篇)
  • 极简GIT使用
  • 【大模型实战篇】华为信创环境采用vllm部署QwQ-32B模型
  • pandas读取Excel数据(.xlsx和.xls)到treeview
  • 【AI面试准备】语言模型、语音、多模态等模型能力评估指标和能力边界
  • 从0开始的c++知识讲解之字符串(1)
  • 使用MGeo模型高精度实现文本中地址识别
  • LeetCode —— 94. 二叉树的中序遍历
  • 洛谷题目:P10480 可达性统计 题解(本题简)
  • PostgreSQL:pgAdmin 4 使用教程
  • Android12 Rom定制设置默认语言为中文
  • Stm32 烧录 Micropython
  • 虚幻商城 Quixel 免费资产自动化入库(2025年版)
  • w~大模型~合集14
  • 腾讯元宝桌面客户端:基于Tauri的开源技术解析
  • Java集合框架终极指南:从基础到高级应用
  • 超全SpringMVC知识点!!(万字总结)
  • UI设计之photoshop学习笔记
  • Java ResourceBundle 资源绑定详解
  • 国标GB28181平台EasyGBS未来研发方向在哪?