HiveSQL题——排序函数(row_number/rank/dense_rank)

news2024/11/18 3:24:18

一、窗口函数的知识点

1.1 窗户函数的定义

        窗口函数可以拆分为【窗口+函数】。窗口函数官网指路:

LanguageManual WindowingAndAnalytics - Apache Hive - Apache Software Foundationicon-default.png?t=N7T8https://cwiki.apache.org/confluence/display/Hive/LanguageManual%20WindowingAndAnalytics

  • 窗口:限定函数的计算范围(窗口函数:针对分组后的数据,从逻辑角度指定计算的范围,并没有从物理上真正的切分,只有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

select
    id
from (
         select
             id,
             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行数据,如果没有就为null
         from (--用户在同一天可能登录多次,需要去重
                  select
                      id,
                      date_format(`date`, 'yyyy-MM-dd') as login_date
                  from user_log
                  group by id, date_format(`date`, 'yyyy-MM-dd')
              ) tmp1
     ) tmp2
where  datediff(next_login_date, login_date) >=2
group by id;

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	["赵敏","小龙女"]
*/
  • 排序函数

      row_number() 、rank()、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 .. )
  • 前后函数 

       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
  • 头尾函数
first_value(column,true)  ---当前窗口column列的第一个数值,如果有null值,则跳过
first_value(column,false) ---当前窗口column列的第一个数值,如果有null值,不跳过
last_value(column,true)  --- 当前窗口column列的最后一个数值,如果有null值,则跳过
last_value(column,false) --- 当前窗口column列的最后一个数值,如果有null值,不跳过

1.4 排序函数

        rank/dense_rank/row_number 函数,一般用于求分组topN。

--  顺序排序——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 .. )

二、实际案例

2.1 每个学生成绩第二高的科目

0 问题描述

    根据学生成绩表,求出每个学生成绩第二高的科目。

1 数据准备

create table if not exists table5
(
    class     string comment '学科',
    student   string comment '学生姓名',
    score     int comment '成绩'
)
    comment '学生成绩表';

insert overwrite table table5 values
('a','吱吱1',100),
('a','吱吱2',60),
('b','吱吱1',80),
('b','吱吱2',70),
('c','吱吱2',50),
('c','吱吱3',90);

2 数据分析

3种排序函数的区别:

  row_number (行号)-- 1 2 3 ;

  rank (重复跳过)--1 1 3;

  dense_rank (重复不跳过) --1 1 2
select
    class,
    student
from (
         select
             class,
             student,
             score,
             dense_rank()  over (partition by student order by score desc) rn
         from table5
     ) tmp1
where rn = 2;

3 小结

    排序函数在分组tpoN场景应用十分广泛,需要注意的是在sql语句中,窗口函数的执行顺序是在where过滤条件之后,所以如果where子句需要用窗口函数作为条件,需要多一层查询,在子查询外面进行。

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

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

相关文章

力扣题集(第一弹)

一日练,一日功;一日不练十日空。 学编程离不开刷题&#xff0c;接下来让我们来看几个力扣上的题目。 1. 242. 有效的字母异位词 题目描述 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 注意&#xff1a;若 s 和 t 中每个字符出现的次数…

粒子群算法求解港口泊位调度问题(MATLAB代码)

粒子群算法&#xff08;Particle Swarm Optimization&#xff0c;PSO&#xff09;是一种基于群体智能的优化算法&#xff0c;它通过模拟鸟群或鱼群的行为来寻找最优解。在泊位调度问题中&#xff0c;目标是最小化所有船只在港时间的总和&#xff0c;而PSO算法可以帮助我们找到一…

07. STP的基本配置

文章目录 一. 初识STP1.1. STP概述1.2. STP的出现1.3. STP的作用1.4. STP的专业术语1.5. BPDU的报文格式1.6. STP的选择原则&#xff08;1&#xff09;选择根桥网桥原则&#xff08;2&#xff09;选择根端口原则 1.7. 端口状态1.8. STP报文类型1.9. STP的收敛时间 二. 实验专题…

如何获得《幻兽帕鲁》隐藏帕鲁唤夜兽?13000个配种配方查询 幻兽帕鲁Steam好评率还在涨 Mac苹果电脑玩幻兽帕鲁 Crossover玩Windows游戏

《幻兽帕鲁》是一款Steam平台热门游戏&#xff0c;开放式大陆和养成式冒险结合&#xff0c;成为2024首款热门游戏&#xff0c;不过由于官方仅发布了Windows版的游戏客户端&#xff0c;Mac用户无法直接玩&#xff0c;好在有Crossover这样的神器&#xff0c;让苹果电脑也能玩上《…

U-Boot学习(6):初始化之_main函数源码分析

在上一节系统初始化之start.S源码分析详解中&#xff0c;我们分析了上电后的代码执行流程&#xff0c;实际上就是对系统特权模式、CP15、向量表等进行配置。最后一步就是进入_main函数了&#xff0c;这个就是U-Boot的主程序了&#xff0c;它完成了对系统内存、堆栈、全局结构体…

非常好用的高效率截图工具-Snipaste

官网:https://zh.snipaste.com/ 帮助文档: https://docs.snipaste.com/zh-cn/

已实现:vue、h5项目如何使用echarts实现雷达图、六边形图表

说实话&#xff0c;要说图表里&#xff0c;最强的应该属于echarts了&#xff0c;不管是接入难度上&#xff0c;还是样式多样性上&#xff0c;还有社区庞大程度上&#xff0c;都是首屈一指的&#xff0c;反观有的人习惯用chart.js了&#xff0c;这个无可厚非&#xff0c;但是如果…

Glide完全解读

一&#xff0c;概述 glide作为android流行的图片加载框架&#xff0c;笔者认为有必要对此完全解读。glide提供了三级缓存、生命周期Destroy后自动移除缓存、自动适配ImageView&#xff0c;以及提供了各种对图片修饰的操作&#xff0c;如剪裁等。本文通过最简单的使用&#xff…

Vim实战:使用 Vim实现图像分类任务(二)

文章目录 训练部分导入项目使用的库设置随机因子设置全局参数图像预处理与增强读取数据设置Loss设置模型设置优化器和学习率调整策略设置混合精度&#xff0c;DP多卡&#xff0c;EMA定义训练和验证函数训练函数验证函数调用训练和验证方法 运行以及结果查看测试完整的代码 在上…

光学3D表面轮廓仪服务超精密抛光技术发展

随着技术的不断进步&#xff0c;精密制造领域对材料表面的处理要求越来越高&#xff0c;超精密抛光技术作为当下表面处理的尖端技术&#xff0c;对各种高精密产品的生产起到了至关重要的作用&#xff0c;已广泛应用于集成电路制造、医疗器械、航空航天、3C电子、汽车、精密模具…

Django知识随笔

目录 1.如何再ajax中传输post数据&#xff1f; 2.在form表单中使用jquery序列化&#xff0c;input框过多。 1.如何再ajax中传输post数据&#xff1f; 在ajax传递的那个网址&#xff0c;会调用你路由的视图函数&#xff0c;在视图函数上面加一句 csrf_exempt 。写上之后会有提…

Docker私有仓库搭建

目录 搭建本地私有仓库 Docker--harbor私有仓库部署与管理 Harbor 简介 什么是Harbor Harbor的特性 Harbor的构成 Harbor 部署 部署 Docker-Compose 服务 ​编辑部署 Harbor 服务 启动 Harbor 进入浏览器http://192.168.20.10进入harbor的客户端 搭建本地私有仓库 …

Shell中sed编辑器

1.简介 sed是一种流编辑器&#xff0c;流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。 sed编辑器可以根据命令来处理数据流中的数据&#xff0c;这些命令要么从命令行中输入&#xff0c;要么存储在一个 命令文本文件中。 2.sed编辑器的工作流程 sed…

12.从项目经理的生存哲学到适配器模式(Adapter Pattern)

如果这个世界没有了项目经理&#xff0c;事情的发展可能并不会如同想象中一样美好&#xff0c;相反&#xff0c;对于开发人员来说可能是噩梦的开始。 比如&#xff1a; 客户因为几个需求的具体实现大发雷霆&#xff0c;甚至开始恶语相向&#xff0c;一通含ma量极高的“斯伯坦语…

【EEG信号处理】ERP相关

ERP&#xff0c;全称为event-related potential&#xff0c;中文是事件相关电位。 首先要明确的一点是&#xff0c;ERP是根据脑电图EEG得到的&#xff0c;他是EEG的一部分&#xff0c;是最常用的时域分析方法 可能有一部分是介绍不到的&#xff0c;望谅解 在维基百科中给的定义…

Vue3的v-model

目录 基本用法 底层机制 v-model 的参数 多个 v-model 绑定 处理 v-model 修饰符 带参数的 v-model 修饰符 例子 总结&#xff1a;Vue 3 中的 v-model 指令与 Vue 2 中的 v-model 相比有一些变化和改进。最显著的变化是&#xff0c;在 Vue 3 中&#xff0c;v-model 可以…

matlab appdesigner系列-仪器仪表4-开关、开关(切换)、开关(翘板)

开关、开关&#xff08;切换&#xff09;、开关&#xff08;翘板&#xff09;&#xff0c;可进行On和Off两种状态切换 示例&#xff1a;开关开启时&#xff0c;可通过滑块调整表盘数值&#xff0c;并有提示框提示 开关关闭时&#xff0c;滑块、表盘数值清零&#xff0c;并有提…

【DDD】学习笔记-理解上下文映射

一个软件系统通常被分为多个限界上下文&#xff0c;这是运用“分而治之”思想来降低业务复杂度的有效手段&#xff0c;设计的难题往往会停留在“如何分”&#xff0c;然而限界上下文之间的“怎么合”问题同样值得关注&#xff0c;分与合遵循的还是软件设计的最高原则——高内聚…

系列五十、idea父子项目忽略部分文件

一、idea父子项目忽略部分文件 **/mvnw **/mvnw.cmd **/.mvn **/target/ .idea **/.gitignore

一进一出模拟量信号隔离变送器

一进一出模拟量信号隔离变送器 捷晟达科技推出一进一出模拟量信号隔离变送器 深圳捷晟达科技推出一款具有隔离,放大,转换保护功能的一进一出的小型隔离变送器设备,该设备可以把模拟量(4-20mA/0-10V等)标准信号转换用户需要的信号,该产品具有抗EMC干扰,可以有效的保护后级设备安…