【第34天】SQL进阶-SQL高级技巧-Window Funtion(SQL 小虚竹)

news2024/12/23 19:39:58

回城传送–》《100天精通MYSQL从入门到就业》

文章目录

  • 零、前言
  • 一、练习题目
  • 二、SQL思路
      • 初始化数据
      • 什么是Window Funtion
      • 窗口函数的分类
      • 语法结构
        • 第一种写法:
        • 第二种写法:
      • 实战体验
        • 序号函数:row_number()
        • 序号函数:rank()
        • 序号函数:dense_rank()
        • 分布函数:percent_rank()
        • 分布函数:cume_dist()
        • 前后函数:LAG(expr, n)
        • 前后函数:LEAD(expr, n)
        • 首尾函数:first_value(expr)
        • 首尾函数:last_value(expr)
        • 其他函数:nth_value(expr, n)
        • 其他函数:ntile(n)
    • 三、总结
    • 四、参考

零、前言

今天是学习 SQL 打卡的第 34 天,每天我会提供一篇文章供群成员阅读( 不需要订阅付钱 )。

希望大家先自己思考,如果实在没有想法,再看下面的解题思路,自己再实现一遍。在小虚竹JAVA社区 中对应的 【打卡贴】打卡,今天的任务就算完成了,养成每天学习打卡的好习惯。

​ 虚竹哥会组织大家一起学习同一篇文章,所以有什么问题都可以在群里问,群里的小伙伴可以迅速地帮到你,一个人可以走得很快,一群人可以走得很远,有一起学习交流的战友,是多么幸运的事情。

​ 我的学习策略很简单,题海策略+ 费曼学习法。如果能把这些题都认认真真自己实现一遍,那意味着 SQL 已经筑基成功了。后面的进阶学习,可以继续跟着我,一起走向架构师之路。

今天的学习内容是:SQL高级技巧-Window Funtion

一、练习题目

题目链接难度
工资最高的人★★★☆☆

二、SQL思路

在这里插入图片描述
在这里插入图片描述

初始化数据

创建表

CREATE TABLE goods(

    id INT PRIMARY KEY AUTO_INCREMENT,
    category_id INT,
    category VARCHAR(15),
    NAME VARCHAR(30),
    price DECIMAL(10,2),
    stock INT,
    upper_time DATETIME
);

插入数据:

INSERT INTO goods(category_id,category,NAME,price,stock,upper_time)
VALUES
(1, '女装/女士精品', 'T恤', 39.90, 1000, '2020-11-10 00:00:00'),
(1, '女装/女士精品', '连衣裙', 79.90, 2500, '2020-11-10 00:00:00'),
(1, '女装/女士精品', '卫衣', 89.90, 1500, '2020-11-10 00:00:00'),
(1, '女装/女士精品', '牛仔裤', 89.90, 3500, '2020-11-10 00:00:00'),
(1, '女装/女士精品', '百褶裙', 29.90, 500, '2020-11-10 00:00:00'),
(1, '女装/女士精品', '呢绒外套', 399.90, 1200, '2020-11-10 00:00:00'),
(2, '户外运动', '自行车', 399.90, 1000, '2020-11-10 00:00:00'),
(2, '户外运动', '山地自行车', 1399.90, 2500, '2020-11-10 00:00:00'),
(2, '户外运动', '登山杖', 59.90, 1500, '2020-11-10 00:00:00'),
(2, '户外运动', '骑行装备', 399.90, 3500, '2020-11-10 00:00:00'),
(2, '户外运动', '运动外套', 799.90, 500, '2020-11-10 00:00:00'),
(2, '户外运动', '滑板', 499.90, 1200, '2020-11-10 00:00:00');

什么是Window Funtion

窗口函数特别适用于需要对分组统计结果中的每一条记录进行计算的场景。

使用窗口函数,你可以为结果集中的每一行返回特定的计算结果,而不是像普通的聚合函数那样,只针对每个分组返回一条记录。通过窗口函数,你可以同时查看原始数据以及与之相关的计算值,为数据分析提供了更丰富的信息。

窗口函数的分类

MySQL8.0版本起开始支持窗口函数。
窗口函数在查询中发挥着类似分组数据的作用,但不同的是:

  • 分组操作是将每个分组的结果聚合为单一的记录。
  • 窗口函数将分组的结果直接融入到查询结果集中的每一条数据记录中

窗口函数分为静态函数和动态函数

  • 静态窗口函数的特点在于其窗口大小是固定的,无论处理的是哪条记录,窗口的边界都保持不变。
  • 动态窗口函数的窗口大小则会根据记录的不同而发生变化。这种变化可能是基于数据的某个字段值,或者是基于记录之间的相对位置。

语法结构

第一种写法:

函数 OVERPARTITION BY 字段名 ORDER BY 字段名 ASC|DESC[window_frame] as 自定义别名

字段解释:

  • 函数: 有多个函数可选择

    • 序号函数:row_number()顺序编号;rank()并列编号,跳过重复的;dense_rank() 并列编号,不会跳过重复的;

    • 分布函数:percent_rank()等级比百分比;cume_dist()累积分布值;

    • 前后函数:LAG(expr, n) 返回当前行的前n行(本组内)的expr值(expr是指定字段);LEAD(expr, n)返回当前行的后n行(本组内)的expr值(expr是指定字段)

    • 首尾函数:first_value(expr) 返回指定字段,截止到当前行,第一行的值;last_value(expr)返回指定字段,截止到当前行,最后一行的值;

    • 其他函数:nth_value(expr, n)返回对应字段,按排序下,第n行的值;ntile(n)将结果集划分为大致相等的n个部分,并为每行数据返回一个“桶”编号,在数据分桶、排名分组等场景有用。

  • OVER:这是定义窗口的关键字,它后面跟着圆括号,用于包含窗口的设置。

  • PARTITION BY:这是可选的子句,用于将结果集分成不同的分区(组)。partition_expression是一个表达式,根据它的值来划分不同的分区。窗口函数将在每个分区内独立计算。

  • ORDER BY:按指定字段排序

  • window_frame:这是可选的子句,用于指定在每个分区中用于窗口函数的行范围。它决定了哪些行包含在计算中。如果未指定window_frame,则窗口函数默认使用所有分区中的所有行。

第二种写法:
SELECT
	...,
	函数 OVER 自定义的窗口名 AS 自定义的列名,
	函数 OVER 自定义的窗口名 AS 自定义的列名2
FROM
	GOODS window 自定义的窗口名 asPARTITION BY 字段名 ORDER BY 字段名 ASC|DESC;

如果窗口在sql中多次使用,则可以提取出来,用自定义窗口名的方式复用,简化sql。

实战体验

序号函数:row_number()

对数据进行顺序排号
例子:查询goods表中每个商品类别对价格降序排列的商品信息。

SELECT 
	*,
	ROW_NUMBER() OVER (PARTITION BY CATEGORY
ORDER BY
	PRICE DESC) AS ROW_NUM
FROM
	GOODS;

我们可以看到,已经对CATEGORY字段进行区分,并对PRICE进行了降序排列,对每个CATEGORY下的商品进行顺序排序。
在这里插入图片描述

序号函数:rank()

并列编号,跳过重复的:如, 1,1,3,4 而不会是 1,2,3,4
例子:查询goods 数据表中类别为“女装/女士精品”的价格最高的4款商品信息。

SELECT 
	*,
	RANK() OVER (PARTITION BY CATEGORY
ORDER BY
	PRICE DESC) AS TOP4PRICE
FROM 
	GOODS
WHERE 
	CATEGORY = '女装/女士精品'
LIMIT 4;

如图所示,TOP4PRICE字段的排序是1,2,2,4
在这里插入图片描述

序号函数:dense_rank()

并列编号,不会跳过重复的;如, 1,1,2,4
例子:查询goods表中每个商品类别对价格降序排列的商品信息。

SELECT
	*,
	DENSE_RANK() OVER(PARTITION BY CATEGORY
ORDER BY
	PRICE DESC) AS PRICE_RANK
FROM 
	GOODS

如图所示,可以看到PRICE_RANK 的排序是1,2,2,3,4,5
在这里插入图片描述

分布函数:percent_rank()

等级比百分比
例子:查询goods 数据表中类别为“女装/女士精品”,价格的百分数排名。

	
SELECT
	RANK() OVER (PARTITION BY CATEGORY_ID
ORDER BY
	PRICE DESC) AS R,
	PERCENT_RANK() OVER (PARTITION BY CATEGORY_ID
ORDER BY
	PRICE DESC) AS PR,
	ID,
	CATEGORY_ID,
	CATEGORY,
	NAME,
	PRICE ,
	STOCK
FROM
	GOODS
WHERE
	CATEGORY_ID = 1;

如图可以看出,按category_id分区数据,并按PRICE降序排列。PERCENT_RANK()函数会计算每个商品在其类别中的百分比排名。
在这里插入图片描述

分布函数:cume_dist()

累积分布值
例子:查询goods 数据表小于或等于当前价格的比例


SELECT
	CUME_DIST() OVER (PARTITION BY CATEGORY_ID
ORDER BY
	PRICE ASC) AS CD,
	ID,
	CATEGORY,
	NAME,
	PRICE
FROM
	GOODS;

cume_dist()=分区中值小于或等于当前行值的行数(包括当前行自身)/分区中的总行数

百褶裙的价格是29.9,没有比它更低的价格,女装/女士精品这个分区有6个,1/6=0.16666666666666667
在这里插入图片描述

前后函数:LAG(expr, n)

返回当前行的前n行(本组内)的expr值(expr是指定字段)
例子:查询goods 数据表同一个分类下,价格降序,前一个商品价格。

SELECT
	*,
	LAG(PRICE, 1) OVER (PARTITION BY CATEGORY_ID
ORDER BY
	PRICE DESC) AS PRE_PRICE
FROM
	GOODS;

在这里插入图片描述

前后函数:LEAD(expr, n)

返回当前行的后n行(本组内)的expr值(expr是指定字段)
例子:查询goods 数据表同一个分类下,价格降序,后一个商品价格。

SELECT
	*,
	LEAD(PRICE, 1) OVER (PARTITION BY CATEGORY_ID
ORDER BY
	PRICE DESC) AS PRE_PRICE
FROM
	GOODS;

在这里插入图片描述

首尾函数:first_value(expr)

返回指定字段,截止到当前行,第一行的值;
例子:取每个商品对应分类下,价格降序下,返回指定字段的第一行的值。

SELECT
   *,
   FIRST_VALUE(PRICE) OVER (PARTITION BY CATEGORY_ID
ORDER BY
   PRICE DESC) AS FV
FROM
   GOODS;

在这里插入图片描述

首尾函数:last_value(expr)

返回指定字段,截止到当前行,最后一行的值;

例子:取每个商品对应分类下,价格降序下,返回指定字段的最后一行的值。

SELECT
   *,
   LAST_VALUE(PRICE) OVER (PARTITION BY CATEGORY_ID
ORDER BY
   PRICE desc) AS LV
FROM
   GOODS;
   

在这里插入图片描述

其他函数:nth_value(expr, n)

返回对应字段,按排序下,第n行的值
注意:这个是截止当前行的排序
在这里插入图片描述

例子:查询每个商品,在对应分类下,价格升序排行在第2,第3行的数据

SELECT
	*,
	NTH_VALUE(PRICE,
	2) OVER (PARTITION BY CATEGORY_ID
ORDER BY
	PRICE ASC) AS SECOND_PRICE,
	NTH_VALUE(PRICE,
	3) OVER (PARTITION BY CATEGORY_ID
ORDER BY
	PRICE ASC) AS THIRD_PRICE
FROM
	GOODS;

在这里插入图片描述
第二种写法:

SELECT
	*,
	NTH_VALUE(PRICE,
	2) OVER w AS SECOND_PRICE,
	NTH_VALUE(PRICE,
	3) OVER w AS THIRD_PRICE
FROM
	GOODS window w as (PARTITION BY CATEGORY_ID
ORDER BY
	PRICE ASC);

在这里插入图片描述

其他函数:ntile(n)

将结果集划分为大致相等的n个部分,并为每行数据返回一个“桶”编号,在数据分桶、排名分组等场景有用。
例子:将商品价格按商品分类,分为三个等级;

SELECT
	NTILE(3) OVER (PARTITION BY CATEGORY_ID
ORDER BY
	PRICE ASC) AS N,
	ID,
	CATEGORY,
	NAME,
	PRICE
FROM
	GOODS;

在这里插入图片描述

三、总结

本文分享了什么是Window Function,并介绍了Window Function的分类,语法结构,并以实战例子介绍每个函数如何使用Window Function。

所以,嗯,这题的答案选。。评论区大声告诉虚竹哥。

四、参考

MySQL进阶技能树–》SQL高级技巧–》Window Function

我是虚竹哥,我们明天见~

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

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

相关文章

AI大模型量化格式介绍(GPTQ,GGML,GGUF,FP16/INT8/INT4)

在 HuggingFace 上下载模型时,经常会看到模型的名称会带有fp16、GPTQ,GGML等字样,对不熟悉模型量化的同学来说,这些字样可能会让人摸不着头脑,我开始也是一头雾水,后来通过查阅资料,总算有了一些…

Leetcode144_二叉树的前序遍历

1.leetcode原题链接:. - 力扣(LeetCode) 2.题目描述 给你二叉树的根节点 root ,返回它节点值的 前序 遍历。 示例 1: 输入:root [1,null,2,3] 输出:[1,2,3]示例 2: 输入&#xf…

如何在PostgreSQL中使用CTE(公共表表达式)来简化复杂的查询逻辑?

文章目录 解决方案步骤示例代码 结论 在处理复杂的SQL查询时,我们经常会遇到需要多次引用子查询或中间结果的情况。这可能会使得查询变得冗长且难以理解。为了解决这个问题,PostgreSQL(以及其他一些SQL数据库系统)引入了公共表表达…

变频器基础原理

文章目录 0. 基本知识1.三相的电压之和为02.正弦交流相量的相量表示法(相量只是表示正弦量,而不等于正弦量 ;只有正弦量才能用相量表示)引入相量表示法目的:一种正弦量的产生方式:正弦量的相量表示,使用欧拉公式表示复数 3.用复数表示正弦量&…

使用JavaScript收集和发送用户设备信息,后端使用php将数据保存在本地json,便于后期分析数据

js代码部分 <script> // 之前提供的JavaScript代码 fetch(https://api.ipify.org?formatjson).then(response > response.json()).then(data > {const deviceInfo {userAgent: navigator.userAgent,platform: navigator.platform,language: navigator.language,…

晶圆制造之MPW(多项目晶圆)简介

01、MPW是什么&#xff1f; 在半导体行业中&#xff0c;MPW 是 "Multi Project Wafer" 的缩写&#xff0c;中文意思是多项目晶圆。MPW 的主要思想是将使用相同工艺的多个集成电路设计放在同一晶圆片上进行流片&#xff08;即制造&#xff09;。这种方法允许多个设计共…

数码摄影色彩构成,数码相机色彩管理

一、资料描述 本套摄影色彩资料&#xff0c;大小58.54M&#xff0c;共有6个文件。 二、资料目录 《抽象彩色摄影集》.阿瑟.pdf 《色彩构成》.pdf 《色彩学》.星云.扫描版.pdf 《摄影色彩构成》.pdf 《数码相机色彩管理》.pdf 数码摄影进阶之4《色彩篇》.pdf 三、资料下…

算法课程笔记——STL题目

长度为2的字符串&#xff0c;当in下标为一&#xff0c;也就是\n,当i&#xff01;n&#xff0c;就是输出空格 &&且 city从citys里面取 加速后就不能混用scanf

HANA SQL消耗内存和CPU线程的限制参数

HANA再处理大数据表相关的复杂Sql时&#xff0c;如果没有设置Memory和CPU线程上限的话&#xff0c;会将HANA的资源占用殆尽&#xff0c;造成HANA无法响应其他Sql请求&#xff0c;导致表现在应用服务器上就是系统卡顿的情况。解决上述问题的办法就是按照下图设置Memory(图1&…

Rust序列化和反序列化

Rust 编写python 模块 必备库 docker 启动 nginx 服务 NGINX 反向代理配置

使用QGIS创建Hexbin地图

Binning是一种用于显示点特征密度的制图技术。分箱涉及将均匀形状的网格覆盖到点数据集上。然后为网格中的每个单元格分配落在其中的点数。然后采用分级颜色分类来直观地显示哪些单元格包含最多数量的点。可以采用不同尺寸的形状&#xff0c;例如矩形、菱形和六边形。 什么是 …

FreeSWITCH 1.10.10 简单图形化界面19 - FreeSWITH性能测试之2核2G和4核4G

FreeSWITCH 1.10.10 简单图形化界面19 - FreeSWITH性能测试之2核心2G和4核心4G 界面预览00、先看使用手册0、先安装FreeSWITCH0、测试备注1、2核心2G内存200分机未开启录音呼叫开启录音呼叫 300分机未开启录音呼叫开启录音呼叫 400分机未开启录音呼叫开启录音呼叫 2、4核心4G内…

《大话西游2》本人收集的十二个单机版游戏,有详细的视频架设教程,云盘下载

《大话西游2》是一款经典的大型多人在线角色扮演游戏&#xff0c;也是一款国风经典的游戏。 有能力的可以架设个外网&#xff0c;让大家一起玩。 《大话西游2》本人收集的十二个单机版游戏&#xff0c;有详细的视频架设教程&#xff0c;值得收藏 下载地址&#xff1a; 链接&…

华为开源自研AI框架昇思MindSpore应用案例:数据处理性能优化

如果你对MindSpore感兴趣&#xff0c;可以关注昇思MindSpore社区 数据是整个深度学习中最重要的一环&#xff0c;因为数据的好坏决定了最终结果的上限&#xff0c;模型的好坏只是去无限逼近这个上限&#xff0c;所以高质量的数据输入&#xff0c;会在整个深度神经网络中起到积极…

ubuntu安装QEMU

qemu虚拟机的使用&#xff08;一&#xff09;——ubuntu20.4安装QEMU_ubuntu安装qemu-CSDN博客 遇到的问题&#xff1a; (1)本来使用git clone https://github.com/qemu/qemu.git fatal: 无法访问 https://github.com/qemu/qemu.git/&#xff1a;GnuTLS recv error (-110): …

Linux-内存文件

1. 基础IO操作 1.1 c语言的IO接口 fopen&#xff1a;打开一个文件&#xff0c;按照指定方式 参数&#xff1a;filename 文件名&#xff0c;也可以是路径&#xff0c;mode&#xff1a;打开方式 返回打开的文件指针 fread&#xff1a;从指定流中读数据 参数&#xff1a;从FIL…

浏览器数据找回

网站上分享的文章应该都是个人的心血&#xff0c;对于一些操作问题导致心血丢失真的很奔溃&#xff0c;终于找到一个弥补的办法&#xff0c;csdn的文章谷歌浏览器亲测有效&#xff0c;理论上其他浏览器的其他网站应该也可以&#xff0c;适用以下场景 把博客编辑当成了编写新博…

【Linux】虚拟机与Xshell及VS Code的连接

一、基础环境 虚拟机&#xff1a;VMware Workstation Pro 虚拟机镜像&#xff1a;ubuntu-18.04.5-desktop-amd64.iso 其他&#xff1a;Xshell 6、Xftp 6、Visual Studio Code 上述软件的安装操作不再赘述&#xff0c;CSDN上有大量的优秀博文&#xff0c;可参考&#xff1a;详细…

【树莓派Linux内核开发】入门实操篇(虚拟机Ubuntu环境搭建+内核源码获取与配置+内核交叉编译+内核镜像挂载)

【树莓派Linux内核开发】入门实操篇&#xff08;虚拟机Ubuntu环境搭建内核源码获取与配置内核交叉编译内核镜像挂载&#xff09; 文章目录 【树莓派Linux内核开发】入门实操篇&#xff08;虚拟机Ubuntu环境搭建内核源码获取与配置内核交叉编译内核镜像挂载&#xff09;一、搭建…

【Hadoop】- YARN架构[7]

前言 Yarn架构是一个用于管理和调度Hadoop集群资源的系统。它是Hadoop生态系统的一部分&#xff0c;主要用于解决Hadoop中的资源管理问题。 通过使用Yarn架构&#xff0c;Hadoop集群中的不同应用程序可以共享集群资源&#xff0c;并根据需要动态分配和回收资源。这种灵活的资…