HiveSQL题——窗口函数(lag/lead)

目录

一、窗口函数的知识点

1.1 窗户函数的定义

1.2 窗户函数的语法

1.3 窗口函数分类

1.4 前后函数:lag/lead

二、实际案例

2.1 股票的波峰波谷

0 问题描述

1 数据准备

2 数据分析

3 小结

2.2 前后列转换(面试题)

0 问题描述

1 数据准备

2 数据分析

3 小结

一、窗口函数的知识点

1.1 窗户函数的定义

         窗口函数可以拆分为【窗口+函数】。窗口函数官网指路:LanguageManual WindowingAndAnalytics - Apache Hive - Apache Software Foundationicon-default.png?t=N7T8https://cwiki.apache.org/confluence/display/Hive/LanguageManual+WindowingAndAnalytics

  • 窗口定义函数计算范围(窗口函数:针对分组后的数据,从逻辑角度指定计算的范围,并没有从物理上真正的切分,只有group by 是物理分组,真正意义上的分组)
  • 函数定义函数计算逻辑
  •  窗口函数的位置:跟sql里面聚合函数的位置一样,from -> join -> on -> where -> group by->select 后面的普通字段,窗口函数 -> having -> order by  -> lmit 。 窗口函数不能跟聚合函数同时出现。聚合函数包括count、sum、 min、max、avg。
  • sql 执行顺序:from -> join -> on -> where -> group by->select 后面的普通字段,聚合函数-> having -> order by -> limit

1.2 窗户函数的语法

       <窗口函数>window_name  over ( [partition by 字段...]  [order by 字段...]  [窗口子句] )

  • window_name:给窗口指定一个别名。
  • over:用来指定函数执行的窗口范围,如果后面括号中什么都不写,即over() ,意味着窗口包含满足where 条件的所有行,窗口函数基于所有行进行计算。
  • 符号[] 代表:可选项;  | : 代表二选一
  •  partition by 子句: 窗口按照哪些字段进行分组,窗口函数在不同的分组上分别执行。分组间互相独立。
  • order by 子句  :每个partition内部按照哪些字段进行排序,如果没有partition ,那就直接按照最大的窗口排序,且默认是按照升序(asc)排列。
  • 窗口子句:显示声明范围(不写窗口子句的话,会有默认值)。常用的窗口子句如下:
    rows between unbounded preceding and  unbounded following; -- 上无边界到下无边界(一般用于求 总和)rows between unbounded preceding and current row;  --上无边界到当前记录(累计值)rows between 1 preceding and current row; --从上一行到当前行rows between 1 preceding and 1 following; --从上一行到下一行rows between current row and 1 following; --从当前行到下一行

     ps: over()里面有order by子句,但没有窗口子句时 ,即: <窗口函数> over ( partition by 字段... order by 字段... ),此时窗口子句是有默认值的->  rows between unbounded preceding and current row (上无边界到当前行)

      此时窗口函数语法:<窗口函数> over ( partition by 字段... order by 字段... ) 等价于

     <窗口函数> over ( partition by 字段... order by 字段... rows between unbounded preceding and current row)
     需要注意有个特殊情况:当order by 后面跟的某个字段是有重复行的时候, <窗口函数> over ( partition by 字段... order by 字段... )  不写窗口子句的情况下,窗口子句的默认值是:range between unbounded preceding and current row(上无边界到当前相同行的最后一行)

    因此,遇到order by 后面跟的某个字段出现重复行,且需要计算【上无边界到当前行】,那就需要手动指定 窗口子句 rows between unbounded preceding and current row ,偷懒省略窗口子句会出问题~

      ps: 窗口函数的执行顺序是在where之后,所以如果where子句需要用窗口函数作为条件,需要多一层查询,在子查询外面进行。

     【例如】求出登录记录出现间断的用户Id

selectid
from (selectid,login_date,lead(login_date, 1, '9999-12-31')over (partition by id order by login_date) next_login_date--窗口函数 lead(向后取n行)--lead(column1,n,default)over(partition by column2 order by column3) 查询当前行的后边第n行数据,如果没有就为nullfrom (--用户在同一天可能登录多次,需要去重selectid,date_format(`date`, 'yyyy-MM-dd') as login_datefrom user_loggroup by id, date_format(`date`, 'yyyy-MM-dd')) tmp1) tmp2
where  datediff(next_login_date, login_date) >=2
group by id;
  • 窗口函数本身也有执行顺序: <窗口函数>over ( partition by  order by   窗口子句 )的执行顺序:over -> partition by -> order by -> 窗口子句 -> 函数

1.3 窗口函数分类

      哪些函数可以是窗口函数呢?(放在over关键字前面的)

  • 聚合函数

sum(column) over (partition by .. order by .. 窗口子句);
count(column) over (partition by .. order by .. 窗口子句);
max(column) over  (partition by .. order by .. 窗口子句);
min(column) over (partition by .. order by .. 窗口子句);
avg(column) over (partition by .. order by .. 窗口子句);

    ps : 高级聚合函数:

         collect_list 收集并形成list集合,结果不去重;

         collect_set 收集并形成set集合,结果去重; 

      举例:

--每个月的入职人数以及姓名select 
month(replace(hiredate,'/','-')),count(*) as cnt,collect_list(name) as name_list
from employee
group by month(replace(hiredate,'/','-'));/*
输出结果
month  cn  name_list
4	    2	["宋青书","周芷若"]
6	    1	["黄蓉"]
7	    1	["郭靖"]
8	    2	["张无忌","杨过"]
9	    2	["赵敏","小龙女"]*/
  • 排序函数

      rank() 、row_number() 、dense_rank() 函数不支持自定义窗口子句。

--  顺序排序——1、2、3
row_number() over(partition by .. order by .. )--  并列排序,跳过重复序号——1、1、3(横向加)
rank() over(partition by .. order by .. )-- 并列排序,不跳过重复序号——1、1、2(纵向加)
dense_rank()  over(partition by .. order by .. )
  • 前后函数 

-- 取得column列的前n行,如果存在则返回,如果不存在,返回默认值default
lag(column,n,default) over(partition by order by) as lag_test
-- 取得column列的后n行,如果存在则返回,如果不存在,返回默认值default
lead(column,n,default) over(partition by order by) as lead_test
  • 头尾函数

---当前窗口column列的第一个数值,如果有null值,则跳过
first_value(column,true) over (partition by ..order by.. 窗口子句) ---当前窗口column列的第一个数值,如果有null值,不跳过
first_value(column,false) over (partition by ..order by.. 窗口子句)--- 当前窗口column列的最后一个数值,如果有null值,则跳过
last_value(column,true) over (partition by ..order by.. 窗口子句) --- 当前窗口column列的最后一个数值,如果有null值,不跳过
last_value(column,false) over (partition by ..order by.. 窗口子句) 

1.4 前后函数:lag/lead

       lead和lag函数,这两个函数一般用于计算差值,上面已介绍其语法。laglead函数不支持自定义窗口子句。

-- 取得column列的前n行,如果存在则返回,如果不存在,返回默认值default
lag(column,n,default) over(partition by order by) as lag_test
-- 取得column列的后n行,如果存在则返回,如果不存在,返回默认值default
lead(column,n,default) over(partition by order by) as lead_test

二、实际案例

2.1 股票的波峰波谷

0 问题描述

    求股票的波峰Crest 和 波谷trough

波峰:当天的股票价格大于前一天和后一天
波谷:当天的股票价格小于前一天和后一天

1 数据准备

create table if not exists table2
(id     int comment '股票id',dt     string comment '日期',price  int comment '价格'
)comment '股票价格波动信息';insert overwrite table table2 values
(1,'2019-01-01',10001),
(1,'2019-01-03',1001),
(1,'2019-01-02',1001),
(1,'2019-01-04',1000),
(1,'2019-01-05',1002),
(1,'2019-01-06',1003),
(1,'2019-01-07',1004),
(1,'2019-01-08',998),
(1,'2019-01-09',997),
(2,'2019-01-01',1002),
(2,'2019-01-02',1003),
(2,'2019-01-03',1004),
(2,'2019-01-04',998),
(2,'2019-01-05',999),
(2,'2019-01-06',997),
(2,'2019-01-07',996);

2 数据分析

  此题容易理解,利用lag()和lead()函数便可以解决。

selectid,dt,price,casewhen price > lag_price and price > lead_price then 'crest'when price < lag_price and price < lead_price then 'trough'end as price_type
from (selectid,dt,price,lag(price, 1) over (partition by id order by dt)  as lag_price,lead(price, 1) over (partition by id order by dt) as lead_pricefrom table2) tmp1;

3 小结

    lead和lag函数一般用于计算当前行与上一行,或者当前行与下一行之间的差值。在用户间断登陆问题中也遇到过此函数。指路:HiveSQL题——用户连续登陆-CSDN博客文章浏览阅读220次,点赞4次,收藏3次。HiveSQL题——用户连续登陆https://blog.csdn.net/SHWAITME/article/details/135900251?spm=1001.2014.3001.5501

2.2 前后列转换(面试题)

0 问题描述

    表temp包含A,B 两列,使用SQL对该B列进行处理,形成C列。按照A列顺序,B列值不变,C列累计技术 B列值变化,则C列重新开始计数,如图所示

   

1 数据准备

with table4 as (select 2010 as A,1 as Bunion allselect 2011 as A,1 as Bunion allselect 2012 as A,1 as Bunion allselect 2013 as A,0 as Bunion allselect 2014 as A,0 as Bunion allselect 2015 as A,1 as Bunion allselect 2016 as A,1 as Bunion allselect 2017 as A,1 as Bunion allselect 2018 as A,0 as Bunion allselect 2019 as A,0 as B
)

2 数据分析

with table4 as (select 2010 as A,1 as Bunion allselect 2011 as A,1 as Bunion allselect 2012 as A,1 as Bunion allselect 2013 as A,0 as Bunion allselect 2014 as A,0 as Bunion allselect 2015 as A,1 as Bunion allselect 2016 as A,1 as Bunion allselect 2017 as A,1 as Bunion allselect 2018 as A,0 as Bunion allselect 2019 as A,0 as B
)selectA,B,row_number() over (partition by T order by A) as C
from (selectA,B,--over (order by A) 本质是 :over(order by rows between unbounded preceding and current row )--省略的是:上无边界到当前行sum(change) over (order by A) Tfrom (selectA,B,-- 向上取一行,取不到的记为0lag(B, 1, 0) over (order by A) as Lag,casewhen B <> lag(B, 1, 0) over (order by A) then 1else 0end   as changefrom table4) tmp1) tmp2;

3 小结

    lead /lag函数常用于差值计算。

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

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

相关文章

使用mkcert生成服务证书和客户端证书并导入到java中

github下载mkcert https://github.com/FiloSottile/mkcert 服务器ip地址为192.168.1.1 生成服务器证书 mkcert 192.168.1.1获取到192.168.1.1.pem和192.168.1.1.key.pem文件 将文件配置到服务器中 本地安装证书 mkcert -install在其他客户端手动导入证书到java中 执行两…

Pytest中doctests的测试方法应用

在 Python 的测试生态中,Pytest 提供了多种灵活且强大的测试工具。其中,doctests 是一种独特而直观的测试方法,通过直接从文档注释中提取和执行测试用例,确保代码示例的正确性。本文将深入介绍 Pytest 中 doctests 的测试方法,包括基本用法和实际案例,以帮助你更好地利用…

Habitat环境学习一:导航任务概述

导航任务 概述&#xff1a; Agent需要导航到环境中的指定位置&#xff0c;而该位置可以由特定的目标形式指定。 PointGoal Navigation&#xff1a;导航到环境中相对于初始位置特定的点&#xff1b; Object Navigation&#xff1a;Agent需要在环境中找到特定的物体&#xff1…

【C++】类和对象(一)

前言&#xff1a;在前面我们带大家初步步入了C&#xff0c;让大家大概知道了他的样子&#xff0c;那今天就可以说我们要正式步入C的大门了&#xff0c;这一章内容的细节比较多各位学习的时候一定要仔细。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f…

leetcode 27.移除元素(python版)

需求 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新长度…

如何多好一个FMEA——SunFMEA软件

尽管FMEA的理念和流程相对简单&#xff0c;但在实际操作中&#xff0c;许多企业发现FMEA的实施并不容易&#xff0c;往往无法达到预期的效果。今天SunFMEA软件和大家一起 SunFMEA软件 首先&#xff0c;FMEA的实施需要跨部门、跨领域的团队合作。然而&#xff0c;在很多企业中&a…

C# Newtonsoft.Json解析json笔记

最近在做数据传报的工作&#xff0c;有解析一个巨复杂的json的需求&#xff0c;所以又学了下 Newtonsoft.Json&#xff0c;感觉挺方便的。 参考思路如下&#xff1a; 1、对象的格式为 名称:值。其中&#xff0c;值可以为对象&#xff08;大括号&#xff09;&#xff0c;也可以…

RX-8564 LC实时时钟模块

.内置 32.768 kHz 晶体单元(频率精度调整完毕) .接口类型&#xff1a;I2C-Bus 接口 (400 kHz) .工作电压范围&#xff1a;1.8 V ~ 5.5 V .计时&#xff08;保持&#xff09;电压范围 &#xff1a;1.0 V ~ 5.5 V / -20 ˚C ~70 ˚C .低待机电流 &#xff1a;275 nA / 3.0…

Acrel-2000MG微电网能量管理系统在工商业储能行业中的应用

一、概述: 在新型电力系统中新能源装机容量逐年提高&#xff0c;但是新能源比如光伏发电、风力发电是不稳定的能源&#xff0c;所以要维持电网稳定&#xff0c;促进新能源发电的消纳&#xff0c;储能将成为至关重要的一环&#xff0c;是分布式光伏、风电等新能源消纳以及电网安…

超强预测模型:二次分解-组合预测

1 长时间序列预测模型Informer Informer是一种基于自注意力机制的序列预测模型&#xff0c;专门用于时间序列预测任务,在时间序列预测领域取得了显著的性能Informer主要特点&#xff1a; 注意力机制与多层编码器-解码器结构 Informer模型引入了全局自注意力和局部自注意力机…

大模型技术关于硬件和操作系统的要求

引言 在人工智能的快速发展中,大模型技术逐渐成为了研究和应用的热点。本文将探讨在大模型技术中,硬件和操作系统的重要性以及具体的要求。 硬件与操作系统要求 一、硬件与软件的平衡 在大模型微调技术的落地应用中,硬件和软件同等重要。用户需要根据具体的应用场景和需求…

Linux操作系统权限相关问题(一站式速通权限)

一、sudo命令 sudo yum install -y sl sudo命令的作用 不切换用户&#xff0c;就想让普通用户以root的身份&#xff0c;执行对应的指令 输入密码时&#xff0c;输入的是自己普通用户的密码&#xff0c;而不是root的密码&#xff01;&#xff01;&#xff01; sudo可以进行…

移动端深度编辑产品技术解决方案

视频编辑已经成为企业宣传、教育、娱乐等多个领域的重要工具。美摄科技凭借其深厚的技术积累和对市场需求的敏锐洞察&#xff0c;开发出业界领先的移动端深度编辑产品&#xff0c;为企业提供高效、专业的视频编辑解决方案。 美摄科技移动端深度编辑产品方案&#xff0c;基于多…

【Vue】2-5、Vue 过滤器

过滤器&#xff08;Filters&#xff09;是 vue 为开发者提供的功能&#xff0c;用于文本的格式化。 【Vue2 可用&#xff0c;Vue3 已经弃用】 过滤器可以用在两个地方&#xff1a; 插值表达式 v-bind 属性绑定 过滤器应该被添加在 JavaScript 表达式的尾部&#xff0c;由“管…

小程序脚本语言——SJS 语法参考

SJS&#xff08;safe/subset javascript&#xff09; 是小程序的一套脚本语言&#xff0c;结合 tyml&#xff0c;可以构建出页面的结构。 注意事项 SJS 的运行环境和其他 JavaScript 代码是隔离的&#xff0c;SJS 中不能调用其他 JavaScript 文件中定义的函数&#xff0c;也不…

那些年与指针的情仇(二)---二级指针指针与数组的那点事函数指针

关注小庄 顿顿解馋(&#xff61;&#xff65;∀&#xff65;)&#xff89;&#xff9e; 欢迎回到我们的大型纪录片《那些年与指针的爱恨情仇》&#xff0c;在本篇博客中我们将继续了解指针的小秘密&#xff1a;二级指针&#xff0c;指针与数组的关系以及函数指针。请放心食用&a…

【AI量化分析】小明在量化中使用交叉验证原理深度分析解读

进行交叉验证好处 提高模型的泛化能力&#xff1a;通过将数据集分成多个部分并使用其中的一部分数据进行模型训练&#xff0c;然后使用另一部分数据对模型进行测试&#xff0c;可以确保模型在未见过的数据上表现良好。这样可以降低模型过拟合或欠拟合的风险&#xff0c;提高模…

浅谈MySQL3种日志

浅谈MySQL3种日志 日志是mysql数据库的重要组成部分&#xff0c;记录着数据库运行期间各种状态信息。mysql日志主要包括错误日志、查询日志、慢查询日志、事务日志、二进制日志几大类。作为开发&#xff0c;我们重点需要关注的是二进制日志(binlog)和事务日志(包括redo log和un…

Qt|QPushButton控件讲解

前提 按钮分为了四种状态&#xff1a;常态、聚焦、按下、禁用 前一段时间更新了MFC框架下CButton的自绘。因为MFC框架下的按钮限制性很高&#xff0c;所以只能由自绘实现各种风格&#xff0c;但是QT框架完美的解决了这个问题&#xff0c;我们只需要了解如何调用&#xff0c;就…

springboot 个人网盘系统 java web网盘文件分享系统 web在线云盘

springboot 个人网盘系统 java web网盘文件分享系统 web在线云盘 开发工具&#xff1a;Eclipse/idea Java开发环境&#xff1a;JDK8.0 Web服务器:Tomcate9.0。 数据库&#xff1a;MySQL数据库。 技术框架&#xff1a;Struts2SpringHibernate和JSP 有详细的源码&#xff0…