HiveSQL——条件判断语句嵌套windows子句的应用

2024-02-09 05:52

本文主要是介绍HiveSQL——条件判断语句嵌套windows子句的应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

注:参考文章:

SQL条件判断语句嵌套window子句的应用【易错点】--HiveSql面试题25_sql剁成嵌套判断-CSDN博客文章浏览阅读920次,点赞4次,收藏4次。0 需求分析需求:表如下user_idgood_namegoods_typerk1hadoop1011hive1221sqoop2631hbase1041spark1351flink2661kafka1471oozie108以上数据._sql剁成嵌套判断https://blog.csdn.net/godlovedaniel/article/details/118220935

0 需求

   基于下表的表结构及数据,求出每个用户每次搜索非广告类型的商品位置排序。假设字段goods_type为26代表该商品类型是广告。

想达到的效果:

1 数据加载

--建表
create table window_goods_test (
user_id int,    --用户id
goods_name string,  --商品名称
goods_type int, --标识每个商品的类型,比如广告,非广告
rk int  --这次搜索下商品的位置,比如第一个广告商品就是1,后面的依次2,3,4...
)ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';-- 加载数据
load data local  inpath '/opt/module/hive_data/window_goods_test.txt' into table window_goods_test ;

 vim window_goods_test.txt

1    hadoop    10    1
1    hive    12    2
1    sqoop    26    3
1    hbase    10    4
1    spark    13    5
1    flink    26    6
1    kafka    14    7
1    oozie    10    8

2 数据分析

    代码分析:最开始的思路:先过滤掉非广告的商品,再重新排序

select user_id,goods_name,goods_type,rk,if(goods_type != 26,row_number() over (partition by user_id order by rk),null) as rk1
from window_goods_test;

输出结果如下:显然没有达到预期的结果。

出错原因在于对窗口函数的执行原理及顺序不了解,可以通过执行计划来判断SQL执行顺序。

explain 
select user_id,goods_name,goods_type,rk,if(goods_type != 26,row_number() over (partition by user_id order by rk),null) as rk1
from window_goods_test;

具体执行步骤如下:

(1)扫描表

(2)按照user_id分组

(3)按照user_id和rk进行升序排序

(4)执行row_number()函数进行分析

(5)使用if进行判断

   由执行计划可以得出 if函数是在row_number()函数之后执行的

  上述sql可以拆解为三部分进行执行:

 step1:扫描表,获取select的结果集

select user_id,goods_name,goods_type,rk
from window_goods_test;

step2:执行窗口函数

select user_id,goods_name,goods_type,rk,row_number() over (partition by user_id order by rk) as rk1
from window_goods_test;

step3:基于step2结果集执行 if判断

因此正确代码如下:

方式一:union all 拆解成两段逻辑

-- 第一段逻辑:先限制goods_type != 26,再排序
selectuser_id,goods_name,goods_type,rk,row_number() over (partition by user_id order by rk) as rk1
from window_goods_test
where goods_type != 26
union all
-- 第二段逻辑:将goods_type = 26的记录的rk1 直接记为null
selectuser_id,goods_name,goods_type,rk,null as rk1
from window_goods_test
where goods_type = 26
order by rk;

 上述代码的缺点:window_goods_test表需要扫描两次,显然不是最优解。

优化的解题思路为:

方式二:

  step1:  partition by分组中先进行 if 语句过滤,如果goods_type!=26则取对应的user_id 进行分组,如果goods_type=26 则置为随机数rand(), 再按照随机数分组

 ps: 这里采用随机数是考虑到万一 goods_type=26的记录数很多,通过rand()随机分组可以将key值打散避免数据倾斜

selectuser_id,goods_name,goods_type,rk,row_number() over (partition byif(goods_type != 26, user_id, rand())order by rk) rk1
from window_goods_test

step2:在step1的外侧利用 if函数进一步判断


selectuser_id,goods_name,goods_type,rk,if(goods_type != 26,row_number() over (partition by if(goods_type != 26, user_id, rand()) order by rk),null) rk1
from window_goods_test

3 小结

   通过本案例得出的结论:

  • case when或if语句中嵌套窗口函数时,条件判断语句的执行顺序是在窗口函数之后的;
  • 窗口函数partition by 子句中是允许嵌套条件判断语句的;

这篇关于HiveSQL——条件判断语句嵌套windows子句的应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/693299

相关文章

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

在MySQL执行UPDATE语句时遇到的错误1175的解决方案

《在MySQL执行UPDATE语句时遇到的错误1175的解决方案》MySQL安全更新模式(SafeUpdateMode)限制了UPDATE和DELETE操作,要求使用WHERE子句时必须基于主键或索引... mysql 中遇到的 Error Code: 1175 是由于启用了 安全更新模式(Safe Upd

Windows设置nginx启动端口的方法

《Windows设置nginx启动端口的方法》在服务器配置与开发过程中,nginx作为一款高效的HTTP和反向代理服务器,被广泛应用,而在Windows系统中,合理设置nginx的启动端口,是确保其正... 目录一、为什么要设置 nginx 启动端口二、设置步骤三、常见问题及解决一、为什么要设置 nginx

在 Windows 上安装 DeepSeek 的完整指南(最新推荐)

《在Windows上安装DeepSeek的完整指南(最新推荐)》在Windows上安装DeepSeek的完整指南,包括下载和安装Ollama、下载DeepSeekRXNUMX模型、运行Deep... 目录在www.chinasem.cn Windows 上安装 DeepSeek 的完整指南步骤 1:下载并安装

5分钟获取deepseek api并搭建简易问答应用

《5分钟获取deepseekapi并搭建简易问答应用》本文主要介绍了5分钟获取deepseekapi并搭建简易问答应用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需... 目录1、获取api2、获取base_url和chat_model3、配置模型参数方法一:终端中临时将加

Python判断for循环最后一次的6种方法

《Python判断for循环最后一次的6种方法》在Python中,通常我们不会直接判断for循环是否正在执行最后一次迭代,因为Python的for循环是基于可迭代对象的,它不知道也不关心迭代的内部状态... 目录1.使用enuhttp://www.chinasem.cnmerate()和len()来判断for

JavaScript中的isTrusted属性及其应用场景详解

《JavaScript中的isTrusted属性及其应用场景详解》在现代Web开发中,JavaScript是构建交互式应用的核心语言,随着前端技术的不断发展,开发者需要处理越来越多的复杂场景,例如事件... 目录引言一、问题背景二、isTrusted 属性的来源与作用1. isTrusted 的定义2. 为

详解如何在React中执行条件渲染

《详解如何在React中执行条件渲染》在现代Web开发中,React作为一种流行的JavaScript库,为开发者提供了一种高效构建用户界面的方式,条件渲染是React中的一个关键概念,本文将深入探讨... 目录引言什么是条件渲染?基础示例使用逻辑与运算符(&&)使用条件语句列表中的条件渲染总结引言在现代

Python调用另一个py文件并传递参数常见的方法及其应用场景

《Python调用另一个py文件并传递参数常见的方法及其应用场景》:本文主要介绍在Python中调用另一个py文件并传递参数的几种常见方法,包括使用import语句、exec函数、subproce... 目录前言1. 使用import语句1.1 基本用法1.2 导入特定函数1.3 处理文件路径2. 使用ex

Spring常见错误之Web嵌套对象校验失效解决办法

《Spring常见错误之Web嵌套对象校验失效解决办法》:本文主要介绍Spring常见错误之Web嵌套对象校验失效解决的相关资料,通过在Phone对象上添加@Valid注解,问题得以解决,需要的朋... 目录问题复现案例解析问题修正总结  问题复现当开发一个学籍管理系统时,我们会提供了一个 API 接口去