SQL-窗口函数合集

目录

  • 1.窗口函数简介
  • 2.窗口的定义
  • 3.相关题目示例
    • 3.1 PERCENT_RANK()
      • 2346 以百分比计算排名
    • 3.2 FIRST_VALUE()/LAST_VALUE()/NTH_VALUE()
      • 2388 将表中的空值更改为前一个值

1.窗口函数简介

MySQL 开窗函数(Window Functions)是 MySQL 8.0 版本引入的一个强大特性,它可以用于计算聚合的同时提供数据行的上下文信息。开窗函数可以分为以下几类:

  • 聚合开窗函数:SUM(), AVG(), MIN(), MAX() 。
  • 排名开窗函数:ROW_NUMBER(), RANK(), DENSE_RANK(), PERCENT_RANK() 。
  • 首尾开窗函数:LEAD(), LAG(),LAST_VALUE(),FIRST_VALUE(),NTH_VALUE()。
  • 其他:CUME_DIST() 、NTILE()。

窗口函数示例1:

mysql> SELECTtime, subject, val,SUM(val) OVER (PARTITION BY subject ORDER BY timeROWS UNBOUNDED PRECEDING)AS running_total,AVG(val) OVER (PARTITION BY subject ORDER BY timeROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)AS running_averageFROM observations;
+----------+---------+------+---------------+-----------------+
| time     | subject | val  | running_total | running_average |
+----------+---------+------+---------------+-----------------+
| 07:00:00 | st113   |   10 |            10 |          9.5000 |
| 07:15:00 | st113   |    9 |            19 |         14.6667 |
| 07:30:00 | st113   |   25 |            44 |         18.0000 |
| 07:45:00 | st113   |   20 |            64 |         22.5000 |
| 07:00:00 | xh458   |    0 |             0 |          5.0000 |
| 07:15:00 | xh458   |   10 |            10 |          5.0000 |
| 07:30:00 | xh458   |    5 |            15 |         15.0000 |
| 07:45:00 | xh458   |   30 |            45 |         20.0000 |
| 08:00:00 | xh458   |   25 |            70 |         27.5000 |
+----------+---------+------+---------------+-----------------+

窗口函数示例2:

mysql> SELECTtime, subject, val,FIRST_VALUE(val)  OVER w AS 'first',LAST_VALUE(val)   OVER w AS 'last',NTH_VALUE(val, 2) OVER w AS 'second',NTH_VALUE(val, 4) OVER w AS 'fourth'FROM observationsWINDOW w AS (PARTITION BY subject ORDER BY timeROWS UNBOUNDED PRECEDING);
+----------+---------+------+-------+------+--------+--------+
| time     | subject | val  | first | last | second | fourth |
+----------+---------+------+-------+------+--------+--------+
| 07:00:00 | st113   |   10 |    10 |   10 |   NULL |   NULL |
| 07:15:00 | st113   |    9 |    10 |    9 |      9 |   NULL |
| 07:30:00 | st113   |   25 |    10 |   25 |      9 |   NULL |
| 07:45:00 | st113   |   20 |    10 |   20 |      9 |     20 |
| 07:00:00 | xh458   |    0 |     0 |    0 |   NULL |   NULL |
| 07:15:00 | xh458   |   10 |     0 |   10 |     10 |   NULL |
| 07:30:00 | xh458   |    5 |     0 |    5 |     10 |   NULL |
| 07:45:00 | xh458   |   30 |     0 |   30 |     10 |     30 |
| 08:00:00 | xh458   |   25 |     0 |   25 |     10 |     30 |
+----------+---------+------+-------+------+--------+--------+

2.窗口的定义

窗口的单位(frame unit):

  • ROWS:表示当前行和 frame 行之间的偏移量是行号之间的差异
  • RANGE:表示当前行和 frame 行之间的偏移量是行值与当前行值之间的差异

窗口的范围:

frame_between:BETWEEN frame_start AND frame_endframe_start, frame_end: {CURRENT ROW| UNBOUNDED PRECEDING| UNBOUNDED FOLLOWING| expr PRECEDING| expr FOLLOWING
}

窗口参数示例:

10 PRECEDING
INTERVAL 5 DAY PRECEDING
5 FOLLOWING
INTERVAL '2:30' MINUTE_SECOND FOLLOWING

注: 如果使用的是RANGE,则需要根据窗口排序中的列,选择对应的时间单位

常用的时间单位:MICROSECOND (microseconds), SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, or YEAR…

mysql> SELECT DATE_ADD('2018-05-01',INTERVAL 1 DAY);-> '2018-05-02'
mysql> SELECT DATE_SUB('2018-05-01',INTERVAL 1 YEAR);-> '2017-05-01'
mysql> SELECT DATE_ADD('2020-12-31 23:59:59',->                 INTERVAL 1 SECOND);-> '2021-01-01 00:00:00'
mysql> SELECT DATE_ADD('2018-12-31 23:59:59',->                 INTERVAL 1 DAY);-> '2019-01-01 23:59:59'
mysql> SELECT DATE_ADD('2100-12-31 23:59:59',->                 INTERVAL '1:1' MINUTE_SECOND);-> '2101-01-01 00:01:00'
mysql> SELECT DATE_SUB('2025-01-01 00:00:00',->                 INTERVAL '1 1:1:1' DAY_SECOND);-> '2024-12-30 22:58:59'
mysql> SELECT DATE_ADD('1900-01-01 00:00:00',->                 INTERVAL '-1 10' DAY_HOUR);-> '1899-12-30 14:00:00'
mysql> SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);-> '1997-12-02'
mysql> SELECT DATE_ADD('1992-12-31 23:59:59.000002',->            INTERVAL '1.999999' SECOND_MICROSECOND);-> '1993-01-01 00:00:01.000001'

3.相关题目示例

3.1 PERCENT_RANK()

PERCENT_RANK()函数返回一个从0到1的数字。

对于指定的行,PERCENT_RANK()计算行的等级减1,除以评估的分区或查询结果集中的行数减1: (rank - 1) / (total_rows - 1) 在此公式中,rank是指定行的等级,total_rows是要计算的行数。

2346 以百分比计算排名

表: Students

+---------------+------+
| Column Name   | Type |
+---------------+------+
| student_id    | int  |
| department_id | int  |
| mark          | int  |
+---------------+------+

student_id 包含唯一值。
该表的每一行都表示一个学生的 ID,该学生就读的院系 ID,以及他们的考试分数。

编写一个解决方案,以百分比的形式报告每个学生在其部门的排名,其中排名的百分比使用以下公式计算:

(student_rank_in_the_department - 1) * 100 / (the_number_of_students_in_the_department - 1)。 percentage 应该 四舍五入到小数点后两位。

student_rank_in_the_department 由 mark 的降序决定,mark 最高的学生是 rank 1。如果两个学生得到相同的分数,他们也会得到相同的排名。

以 任意顺序 返回结果表。

结果格式如下所示。

示例 1:

输入:
Students 表:

+------------+---------------+------+
| student_id | department_id | mark |
+------------+---------------+------+
| 2          | 2             | 650  |
| 8          | 2             | 650  |
| 7          | 1             | 920  |
| 1          | 1             | 610  |
| 3          | 1             | 530  |
+------------+---------------+------+

输出:

+------------+---------------+------------+
| student_id | department_id | percentage |
+------------+---------------+------------+
| 7          | 1             | 0.0        |
| 1          | 1             | 50.0       |
| 3          | 1             | 100.0      |
| 2          | 2             | 0.0        |
| 8          | 2             | 0.0        |
+------------+---------------+------------+

解释:
对于院系 1:

  • 学生 7:percentage = (1 - 1)* 100 / (3 - 1) = 0.0
  • 学生 1:percentage = (2 - 1)* 100 / (3 - 1) = 50.0
  • 学生 3:percentage = (3 - 1)* 100 / (3 - 1) = 100.0
    对于院系 2:
  • 学生 2: percentage = (1 - 1) * 100 / (2 - 1) = 0.0
  • 学生 8: percentage = (1 - 1) * 100 / (2 - 1) = 0.0

答案:

select 	student_id,department_id,round((percent_rank() over (partition by department_id order by mark desc))*100,2) as percentage
from Students

3.2 FIRST_VALUE()/LAST_VALUE()/NTH_VALUE()

FIRST_VALUE() 函数的作用是返回子集中第一行的指定列数据,该函数的语法如下:


FIRST_VALUE(expr)
OVER ([partition_definition] [order_definition] [frame_clause]
)

其中,expr 为要获取数据的列明或者表达式,partition_definition 和 partition_definition 与 ROW_NUMBER() 函数一致;

frame_clause 的语法如下:

frame_unit {<frame_start>|<frame_between>}

LAST_VALUE() 和 FIRST_VALUE() 十分类似,区别在于 LAST_VALUE() 返回的是子集中的最后一条数据的指定列数据

NTH_VALUE() 的作用是获取指定 frame 中的第
N
个记录行的指定数据,对应的函数语法如下所示:


NTH_VALUE(expr, N)
OVER ([partition_definition] [order_definition] [frame_clause]
)

2388 将表中的空值更改为前一个值

表: CoffeeShop

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| drink       | varchar |
+-------------+---------+

id 是该表的主键(具有唯一值的列)。
该表中的每一行都显示了订单 id 和所点饮料的名称。一些饮料行为 null。

编写一个解决方案将 drink 的 null 值替换为前面最近一行不为 null 的 drink。保证表第一行的 drink 不为 null。

返回 与输入顺序相同的 结果表。

查询结果格式示例如下。

示例 1:

输入:
CoffeeShop 表:

+----+-------------------+
| id | drink             |
+----+-------------------+
| 9  | Rum and Coke      |
| 6  | null              |
| 7  | null              |
| 3  | St Germain Spritz |
| 1  | Orange Margarita  |
| 2  | null              |
+----+-------------------+

输出:

+----+-------------------+
| id | drink             |
+----+-------------------+
| 9  | Rum and Coke      |
| 6  | Rum and Coke      |
| 7  | Rum and Coke      |
| 3  | St Germain Spritz |
| 1  | Orange Margarita  |
| 2  | Orange Margarita  |
+----+-------------------+

解释:
对于 ID 6,之前不为空的值来自 ID 9。我们将 null 替换为 “Rum and Coke”。
对于 ID 7,之前不为空的值来自 ID 9。我们将 null 替换为 “Rum and Coke”。
对于 ID 2,之前不为空的值来自 ID 1。我们将 null 替换为 “Orange Margarita”。
请注意,输出中的行与输入中的行相同。

答案:


select id,first_value(drink) over(partition by group_id order by row_id) as drink
from(select *,sum(IF(drink is null, 0, 1)) over(order by row_id) as group_idfrom(select *,row_number() over() as row_idfrom coffeeshop) t0) t1
;

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

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

相关文章

k8s metrics-server服务监控pod 的 cpu、内存

项目场景&#xff1a; 需要开启指标服务&#xff0c;依据pod 的 cpu、内存使用率进行自动的扩容或缩容 pod 的数量 解决方案&#xff1a; 下载 metrics-server 组件配置文件&#xff1a; wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/…

植物大战僵尸杂交版 MacBook 苹果电脑下载安装详细教程

最近老是看到别人玩植物大战僵尸杂交版&#xff0c;可是找了一圈发现都是PC版本的&#xff0c;原来游戏作者只做了一个PC版本&#xff0c;还好最终没有放弃终于在 Mac 上安装上了植物大战僵尸杂交版 版本是 2.0.88 真的蛮好玩的就是关卡有亿点点难&#xff0c;我最爱玩无尽模式…

一站式解决ComfyUI安装、调试和界面操作,附安装包 C001

点击打开以上网页&#xff0c;页面往下拉&#xff0c;找到“Direct link to download”&#xff0c;点击即可下载官方安装包。 下载完成后&#xff0c;将安装包移动到你想要安装的地方&#xff0c;解压&#xff08;推荐使用7-Zip&#xff09;&#xff0c;然后点击“run_nvidia_…

C++中的观察者模式

目录 观察者模式&#xff08;Observer Pattern&#xff09; 实际应用 股票价格监控系统 发布-订阅系统 总结 观察者模式&#xff08;Observer Pattern&#xff09; 观察者模式是一种行为型设计模式&#xff0c;它定义了对象间的一对多依赖关系。当一个对象的状态发生改变…

无需插件脚本,IDEA配置多服务一键启动

分享本教程的初衷是本人在本地调试时业务场景中需要调用多个服务&#xff0c;并且每次为了找到需要启动的服务花了很多不必要的时间&#xff0c;我相信很多同为开发的小伙伴也有和我一样的困扰。但是学会这招后多个服务需要同时启动时仅需一键即可搞定。接下来让我们一步步设置…

C++方法封装成dll及C#调用示例

1,编译生成dll时可能出现错误&#xff0c;解决办法&#xff1a;pch.h文件头部&#xff0c;添加声明 #define _CRT_SECURE_NO_WARNINGS 2, c头文件声明 extern "C" __declspec(dllexport) char* getvalue(const char * param1, const char * param2); 3, c方法实现…

【PasteSpider】的集群组件【PasteCluster】(让你的项目快速支持集群模式)的思路及实现(含源码)

PasteSpider是什么? 一款使用.net编写的开源的Linux容器部署助手&#xff0c;支持一键发布&#xff0c;平滑升级&#xff0c;自动伸缩&#xff0c;Key-Value配置&#xff0c;项目网关&#xff0c;环境隔离&#xff0c;运行报表&#xff0c;差量升级&#xff0c;私有仓库&…

vue在hash路由模式下实现点击定位滑动

背景&#xff1a;一般是使用锚点来实现dom的定位&#xff0c;但在hash模式下&#xff0c;这种方式不行&#xff0c;会刷新路由&#xff0c;没法实现dom定位的效果。 其实scrollIntoView就可以解决这个问题&#xff0c;scrollIntoView可以将调用它的元素滚动到浏览器窗口的可见…

物联网网关和飞鸟物联平台如何助力其实现智能化升级,提升生产效率-天拓四方

随着工业4.0时代的到来&#xff0c;物联网技术逐渐成为推动工业转型升级的关键力量。物联网网关作为连接工业设备与网络的核心枢纽&#xff0c;在工业自动化、数据收集与分析等方面发挥着越来越重要的作用。本案例将围绕一家知名制造企业&#xff0c;展示物联网网关和飞鸟物联平…

vue中v-bind控制class和style

当使用v-bind指令控制class和style时&#xff0c;可以通过动态绑定的方式根据不同的条件来添加或移除class&#xff0c;以及改变元素的样式。 1. 控制class 通过v-bind:class可以动态绑定class属性。可以使用对象语法、数组语法或者计算属性来实现。 对象语法&#xff1a;使用…

关于ImportError: attempted relative import with no known parent package解决

问题 我的项目结构如下&#xff1a; my_project/ ├── utils/ │ ├── __init__.py │ └── config.py └── scripts/├── __init__.py└── train.py当我在train.py中 尝试导入config中的模块时&#xff0c;即 from ..utils.config import *&#xff0c;报错…

提升消费者满意度的五星售后服务认证

在当今竞争激烈的市场环境中&#xff0c;消费者满意度是企业取得成功的重要因素。五星售后服务认证作为一种权威性认证&#xff0c;可以显著提高消费者满意度&#xff0c;增强企业的竞争力。本文将从四个方面探讨五星售后服务认证如何提高消费者满意度。 五星售后服务认证是由国…

SpringCash

文章目录 简介引入依赖application.yml配置常用注解使用1. 启动类添加注解使用方法上添加注解 简介 Spring Cache是一个框架&#xff0c;实现了基于注解的缓存功能底层可以使用EHCache、Caffeine、Redis实现缓存。 注解一般放在Controller的方法上&#xff0c;CachePut 注解一…

高精度定位技术的必要性与实际应用

在当今社会&#xff0c;随着科技的飞速发展&#xff0c;高精度精准定位技术已成为一项不可或缺的基础技术&#xff0c;其应用范围涉及军事、航空、智能交通、无人驾驶、智慧城市建设等众多领域。高精度精准定位不仅为人们的日常生活带来极大便利&#xff0c;还对提升国家的科技…

鸿蒙轻内核A核源码分析系列六 MMU协处理器(1)

在前面系列分析虚实映射时&#xff0c;涉及到了一些MMU协处理器与相关的汇编代码没有深入讲解。本文来专门分析那些协处理器与汇编代码。 本文中所涉及的源码&#xff0c;以OpenHarmony LiteOS-A内核为例&#xff0c;均可以在开源站点 https://gitee.com/openharmony/kernel_l…

mysql性能优化知识点

MySQL性能优化是一个多方面的议题&#xff0c;涉及数据库设计、查询优化、服务器配置、索引管理等多个层面。 以下是一些关键的优化策略&#xff1a; 1、优化简介 使用SHOW STATUS语句查询一些MySQL数据库性能参数&#xff0c;格式如下&#xff1a; SHOW STATUS LIKE value;…

Presidents of America(1789-1860)

Presidents of America preface 美国总统&#xff0c;是美利坚合众国的国家元首、政府首脑与三军统帅&#xff0c;是当今世界权力最高的人。美国总统是根据1787年通过的美国宪法而设立&#xff0c;行使宪法赋予的行政权。截至目前&#xff0c;美国一共有过44位总统(45任&…

项目中的增删改查

1.增加&#xff1a; 接口定义&#xff1a;在Spring Boot的Controller&#xff08;控制层&#xff09;定义添加医院的接口&#xff0c;使用POST方法&#xff0c;并接收医院信息的JSON数据。数据校验&#xff1a;在接收到数据后&#xff0c;进行必要的数据校验&#xff0c;确保数…

运行mvn命令打包项目jar包报错?“Fatal error compiling: 无效的目标发行版: 19 ”, 让我来看看~

最近写实验&#xff0c;要打包项目&#xff0c;但是不管是在cmd运行“mvn clean package -Dmaven.test.skiptrue”命令&#xff0c;还是在idea上去操作&#xff0c;都出现了这样的一个错误&#xff1a; [EROR] Failed to exeoute goal org.apache.maven.plugins:maven-comnpile…

CCRC信息安全服务资质认证是什么

什么是CCRC认证&#xff1f; CCRC 全称 China Cybersecurity Review Technology and Certification Center。CCRC认证是指中国网络安全审查技术与认证中心进行的信息安全服务资质认证。简称信息安全服务资质认证。 CCRC&#xff0c;即中国网络安全审查技术与认证中心&#xff0…