mysql窗口函数用法_mysql实现窗口函数

mysql窗口函数用法_mysql实现窗口函数一,MySQl8.0窗口函数窗口函数适用场景:对分组统计结果中的每一条记录进行计算的场景下,使用窗口函数更好;可以跟Hive的对比着看:点我,特么的花了一晚上整理,没想到跟Hive的基本一致,还不因为好久没复习博客了,淦注意:mysql因为没有array数据结构,无法像Hive一样行列进行转换;1.1窗口函数分类MySQL从8.0版本开始支持窗口函数。窗口函数的作用类似于在查询中对数据进行分组,不同的是,分组操作会把分组的结果聚合成一条记录,而窗口函数是

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

一, MySQl 8.0 窗口函数

窗口函数适用场景: 对分组统计结果中的每一条记录进行计算的场景下, 使用窗口函数更好, 注意, 是每一条!! 因为MySQL的普通聚合函数的结果(如 group by)是每一组只有一条记录!!!

可以跟Hive的对比着看: 点我, 特么的花了一晚上整理, 没想到跟Hive 的基本一致, 还不因为好久没复习博客了, 淦

注意: mysql 因为没有array数据结构, 无法像Hive一样 行列进行转换;

1.1 窗口函数分类

  • MySQL从8.0版本开始支持窗口函数。窗口函数的作用类似于在查询中对数据进行分组,不同的是,分组操作会把分组的结果聚合成一条记录,而窗口函数是将分组的结果置于每一条数据记录中
  • 窗口函数可以分为静态窗口函数动态窗口函数
    • 静态窗口函数的窗口大小是固定的, 不会因为记录的不同而不同;
    • 动态窗口函数的窗口大小会随着记录的不同而变化;

窗口函数总体上可以分为序号函数, 分布函数, 前后函数, 首尾函数和其他函数;

在这里插入图片描述

1.2 语法结构

  • 窗口函数的语法结构:
    • 函数 OVER ([PARTITION BY 字段名 ORDER BY 字段名 ASC|DESC])
    • 或者是 函数 OVER 窗口名 … WInDOW 窗口名 AS ([PARTITION BY 字段名 ORDER BY 字段名 ASC|DESC])

OVER 关键字指定窗口的范围;

  • 如果省略后面括号中的内容,则窗口会包含满足WHERE条件的所有记录,窗口函数会基于所有满足WHERE条件的记录进行计算。
  • 如果OVER关键字后面的括号不为空,则可以使用如下语法设置窗口。

PARTITION BY 子句: 指定窗口函数按照哪些字段进行分组, 分组后, 窗口函数可以在每个分组中分别执行;
ORDER BY 子句: 指定窗口函数按照哪些字段进行排序, 执行排序操作使窗口函数按照排序后的数据记录的顺序进行编号;
FRAME 子句: 为分区中的某个子集定义规则, 可以用来作为滑动窗口使用;


1.3 窗口函数?

准备表和数据:

  • 创建表:

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');

下面针对goods表中的数据来验证每个窗口函数的功能。

1. 序号函数

序号函数是按照一定的分组规则对每一组的数据排序并创建一个序号列

1.1 row_number() – 单纯的对每一组数据编号

函数 功能
row_number() 对数据中的序号进行顺序显示

[案例]

1.1 查询 goods 数据表中每个商品分类下价格降序排列的各个商品信息。


SELECT 
	*,
	ROW_NUMBER() OVER (PARTITION BY category ORDER BY price DESC) AS row_num
FROM goods;

在这里插入图片描述

1.2 查询 goods 数据表中每个商品分类下价格最高的3种商品信息。

SELECT 
	*	
FROM 
	(
	SELECT 
		*,
		ROW_NUMBER() OVER (PARTITION BY category ORDER BY price DESC) AS top3Price 
	FROM goods
	) AS t

WHERE 
	top3Price <= 3

在这里插入图片描述

在名称为“女装/女士精品”的商品类别中,有两款商品的价格为89.90元,分别是卫衣和牛仔裤。两款商品的序号都应该为2,而不是一个为2,另一个为3。此时,可以使用RANK()函数和DENSE_RANK()函数解决;

1.2 rank() – 排序每一组的某一字段, 同等级同序号前后不连续

函数 功能
rank() 对序号进行并列排序, 指定字段数值相同(同一等级),则会产生相同序号记录,且产生序号间隙,
如, 1,1,3,4 而不会是 1,2,3,4(row_number的结果), 也不是 1,1,2,3,4 (dense_rank的结果)
rank函数没有参数,但需要指定按照那个字段进行排名,所以使用rank函数必须用order by参数,order by的排序字段就是排名字段

1.3

在这里插入图片描述

1.4 使用RANK()函数获取 goods 数据表中类别为“女装/女士精品”的价格最高的4款商品信息。

// 常规思路
SELECT *
FROM goods
WHERE category = '女装/女士精品'
ORDER BY price DESC
LIMIT 4

#窗口函数rank: 并列
SELECT 
	*,
	RANK() OVER (PARTITION BY category ORDER BY price DESC) AS top4Price
FROM 
	goods
WHERE 
	category = '女装/女士精品'
LIMIT 4;

在这里插入图片描述

1.3 dense_rank() – 排序每一组的某一字段, 同等级同序号前后也连续

函数 功能
dense_rank() 对序号进行并列排序, 指定字段数值相同(同一等级),则会产生相同序号记录,且产生序号间隙,

1.5

在这里插入图片描述

1.6

在这里插入图片描述

可以看到,使用DENSE_RANK()函数得出的行号为1、2、2、3,相同价格的商品序号相同,且后面的商品序号是连续的

2. 分布函数

2.1 percent_rank() – 等级值百分比, (rank – 1)/ (rows – 1)

函数 功能
percent_rank() 计算分区或结果集中行的百分位数排名
每行按照公式(rank-1)/ (rows-1)进行计算。其中,rank为RANK()函数产生的序号rows当前窗口(当前组)的总行数

在这里插入图片描述

2.2 cume_dist() – 累积分布值, <=当前rank值的行数 / 分组内总行数

函数 功能
cume_dist() 分组内<=当前rank值的行数 / 分组内总行数

在这里插入图片描述

3. 前后函数

3.1 LAG(expr, n) – 返回当前行的前n行(本组内)的expr值

函数 功能
LAG(expr, n) 返回当前行的前n行(本组)的expr值
lag允许你在每一个分组内, 从当前行向前看n行数据
n(也叫offset)是从当前行偏移的行数,以获取值。offset必须是一个非负整数。如果offset为零,则LAG()函数计算当前行的值。如果省略 offset,则LAG()函数默认使用n=1, 向前看一个数据。

在这里插入图片描述

3.2 LEAD(expr, n)

函数 功能
LEAD(expr, n) 返回当前行的后n行(本组)的expr值

在这里插入图片描述

4. 首位函数

4.1 first_value(expr) , last_value(expr)

在这里插入图片描述

5. 其他函数

5.1 nth_value(expr, n)

在这里插入图片描述

5.2 ntile(n)

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/185701.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • fsync、synchronous_commit 的简单测试

    fsync、synchronous_commit 的简单测试fsync(boolean)如果打开这个参数,PostgreSQL服务器将尝试确保更新被物理地写入到磁盘,做法是发出fsync()系统调用或者使用多种等价的方法(见wal_sync_method)。这保证了数据库集簇在一次操作系统或者硬件崩溃后能恢复到一个一致的状态。虽然关闭fsync常常可以得到性能上的收益,但当发生断电或系统崩溃时可能造成不可恢复的数据损坏。因此,只有在能很容易地从外部数据中重

    2022年5月31日
    41
  • 经常使用的DB2命令(2)

    经常使用的DB2命令(2)

    2022年1月28日
    43
  • acwing-2326. 王者之剑(最小割之最大点权独立集)「建议收藏」

    acwing-2326. 王者之剑(最小割之最大点权独立集)「建议收藏」给出一个 n×m 网格,每个格子上有一个价值 vi,j 的宝石。Amber 可以自己决定起点,开始时刻为第 0 秒。以下操作,在每秒内按顺序执行。若第 i 秒开始时,Amber 在 (x,y),则 Amber 可以拿走 (x,y) 上的宝石。在偶数秒时(i 为偶数),则 Amber 周围 4 格的宝石将会消失。若第 i 秒开始时,Amber 在 (x,y),则在第 (i+1) 秒开始前,Amber 可以马上移动到相邻的格子 (x+1,y),(x−1,y),(x,y+1),(x,y−1) 或原地不动

    2022年8月9日
    6
  • SBC,sip介绍[通俗易懂]

    SBC,sip介绍[通俗易懂]SBC介绍

    2025年9月5日
    4
  • opencv3编程入门_java基础与入门教程

    opencv3编程入门_java基础与入门教程——韦访 201810111、概述想学习图像处理,不管是机器学习也好,深度学习也好,不会点OpenCV好像有点说不过去吧?所以,现在开始OpenCV的学习。2、读写图片先从图片的读写开始,opencv读取图片的函数是imread,默认情况下,imread函数返回BGR格式的图像,可以用imwrite函数将数据写到本地。下面的代码会将JPG图片转成PNG。import…

    2022年10月3日
    2
  • FileStream文件流类「建议收藏」

    FileStream文件流类「建议收藏」主要讲解以下几个方面:1,FileStream文件流类,2,FileStream文件流类的创建,3,FileMode和FileAccess,FileShare方法基本介绍及注意事项用File类提供的方法在创建或打开文件时,总是会产生一个FileStream对象。类FileStream是个什么样的类?通过它的对象,怎样完成对文件的操作呢?1.FileStream文件流类简介F

    2022年7月21日
    18

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号