SQL窗口分析函数使用详解系列三之偏移量类窗口函数

admin3周前笔记25

1.综述

本文以HiveSQL语法进行代码演示。

对于其他数据库来说同样也适用,比如SparkSQL,FlinkSQL以及Mysql8,Oracle,SqlServer等传统的关系型数据库。

本节介绍Hive窗口分析函数中的第三类窗口函数:偏移量类窗口函数。

在实际的应用场景中,顾名思义,偏移量分析函数主要应用于求解和指定偏移数据的差值。例如和上一行数据差值,和下一行数据差值。

有什么实际意义呢?例如,每行数据是天粒度的,那么上下行的差值计算就是前后天的数据增长量或者减少量,比left join,right join的方式更为简单,效率更高。

1.1 偏移量类窗口函数

lead() over();lag() over();first_value() over();


1.2 窗口函数语法

分析函数 over(partition by 列名 order by 列名 rows between 开始位置 and 结束位置)

具体解析

over()括号内为空时,是直接进行计算。

其中partition by 列名是按指定列进行分组,进而进行计算。

最后的order by 列名 是按照指定列进行排序,进而进行计算。

1.3 基础数据准备

create table if not exists temp.user_info (
  `id` bigint comment '用户id',
  `client` string comment '客户端',
  `gender` int comment '性别,0女1男',
  `constellation` string comment '星座',
  `age` int comment '年龄',
  `pv` bigint comment '访问量',
  `chat_num` bigint comment '聊天次数') comment '用户信息测试临时表'

数据预览

idclientgenderconstellationagepvchat_num
1ios0处女座291743
2ios1双鱼座262632
3android1双鱼座3523239
4ios1水瓶座32573
5ios1射手座33676
6ios1双子座36815
7ios1狮子座29684
8ios1狮子座28193
9ios0射手座324792
10ios1白羊座2625536

2.各偏移量函数的使用

2.1 lag

  • 功能

Lag函数用于获取指定列的前n(取决于偏移量的设置)个行的值,按照我们设定的分区以及排序规则。

  • 语法

lag(column_name, offset, default_value) over (partition by partition_col order by order_col)

① column_name要查询的列名

② offset 要查找的偏移量,即要获取的行数的偏移量,默认为1,例如往前1行或者n行。

③ default_value 一个可选的默认值(当没有找到前一个行时返回的值

  • 示例

按客户端分组,按id排序,取出上一行的年龄。

select id,client,age,lag(age,1,10) over(partition by client order by id) as lag_1_age from temp.user_infowhere id <= 10order by id;

数据结果

idclientagelag_1_age
1ios2910
2ios2629
3android3510
4ios3226
5ios3332
6ios3633
7ios2936
8ios2829
9ios3228
10ios2632

可以看到id为1的用户没有上一行,所以取到的值为我设置的默认值10.如果不设置默认值,返回null

Id 为2的用户渠道的偏移值是id为1的用户的年龄。

  • 拓展使用

偏移量最常见的使用是当数据最细粒度为天粒度时,查询该用户的前一天行为和今天行为的差值或者相比上一日上涨或者下降百分比等。伪SQL

-- 这里省略了偏移量和默认值select id,pv,dt,pv-lag_pv as gap_pv  -- 当日和上一日的pv差值 from (		select id,pv,dt,lag(pv) over(partition by id order by dt) as lag_pv from temp.user_pv_info
) a

2.2 lead

  • 功能

和lag类似,却刚好相反。是取向下的偏移量的值。进而进行差值计算等。

用于获取指定列的后n(取决于偏移量的设置)个行的值,按照我们设定的分区以及排序规则。

  • 语法

lead(column_name, offset, default_value) over (partition by partition_col order by order_col)

① column_name要查询的列名

② offset 要查找的偏移量,即要获取的行数的偏移量,默认为1,例如往前1行或者n行。

③ default_value 一个可选的默认值(当没有找到前一个行时返回的值)

  • 示例

按客户端分组,按id排序,取出下二行的年龄。

select id,client,age,lead(age,2,10) over(partition by client order by id) as lead_2_age from temp.user_infowhere id <= 10order by id;

数据结果

idclientagelead_2_age
1ios2932
2ios2633
3android3510
4ios3236
5ios3329
6ios3628
7ios2932
8ios2826
9ios3210
10ios2610

如上,我把偏移量设置为2,可以看到id为9和10的向下两行没有数据。

  • 拓展使用

和lag使用场景一致,很多场景lag和lead都可以互换,需要设置排序是正序或者倒序的区别。

2.3 first_value

  • 功能

first_value用于返回分组中的第一个值,按指定的排序列。我们在使用中可以根据特定的排序规则来确定和查询获取每个分组的第一个值

  • 语法

first_value(expression) over(
	[partition by 列名1,列名2]
  [order by 列名3,列名4]
)

① expression要获取第一个值的列或者表达式

② partition by 用于指定分组的列

③ order by 用于指定排序的列

  • 示例

查询不同客户端,年龄最小的用户。

select id,client,age,first_value(age) over(partition by client order by age) as min_age from temp.user_infowhere id <= 10order by id;

数据结果

idclientagemin_age
1ios2926
2ios2626
3android3535
4ios3226
5ios3326
6ios3626
7ios2926
8ios2826
9ios3226
10ios2626

可以看到当前ios客户端的最小年龄为26,android客户端最小年龄为35.

  • 拓展使用

这样查有什么用呢?

例如可以进一步求解当前用户年龄和最小年龄或者最大年龄的差值。

如果是其他例如销售数据,或者活跃数据等,就更加有实用意义了。

总之,SQL窗口分析函数能够支持我们在更多的场景直接进行数据处理,进而更加深入和高效的进行数据分析


相关文章

Linux压缩好帮手bzip2

Linux压缩好帮手bzip2

Linux 中有几个文件压缩和解压缩工具,比如gzip、7-zip、Lrzip、PeaZip 等等。本篇教程中,我们将介绍如何在 Linux 中使用 bzip2 工具压缩及解压缩.bz2文件...

玩转 Windows 10 中的 Linux 子系统

玩转 Windows 10 中的 Linux 子系统

Web 开发人员们不用再苦恼所用的 Windows 开发平台上没有合适的 Linux 工具和库了。WSL 是由 Windows 内核团队与 Canonical 合作设计和开发的,可以让 Windows...

grep 命令的 12 个实例

grep 命令的 12 个实例

你是否遇到过需要在文件中查找一个特定的字符串或者样式,但是不知道从哪儿开始?那么,就请grep来帮你吧。grep是每个Linux发行版都预装的一个强有力的文件模式搜索工具。无论何种原因,如果你的系统没...

消息队列 MQ 入门

消息队列 MQ 入门

MQ 的概念MQ 全称 Message Queue(消息队列),是在消息的传输过程中保存消息的容器。用于分布式系统之间进行通信。MQ 的优势解耦系统的耦合性越高,容错性就越低,可维护性就越低。使用 M...

redis和memcached的区别

权威比较Redis的作者Salvatore Sanfilippo曾经对这两种基于内存的数据存储系统进行过比较:Redis支持服务器端的数据操作:Redis相比Memcached来说,拥有更多的数据结构...

uptime 命令介绍

uptime 命令介绍

Linux uptime 命令望名生义,uptime 命令告诉你系统启动up了(运行了)多长时间。这是语法:uptime [options]这个工具的 man 页是这么说的:uptime会在...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。