【面试题】Hive 查询:如何查找用户连续三天登录的记录
1. 需求概述
在分析用户行为时,查询用户的连续登录数据是一个常见需求。例如,我们需要找出每个用户连续三天登录的记录。给定一个包含用户登录记录的表,我们需要对这些数据进行处理,提取出用户连续三天登录的日期。
2. 问题说明
假设我们有一个用户登录记录表 user_log,表结构如下:
| id | dt |
|---|---|
| 1 | 2024-04-25 |
| 1 | 2024-04-26 |
| 1 | 2024-04-27 |
| 1 | 2024-04-28 |
| 1 | 2024-04-30 |
| 1 | 2024-05-01 |
| 1 | 2024-05-02 |
| 1 | 2024-05-04 |
| 1 | 2024-05-05 |
| 2 | 2024-04-25 |
| 2 | 2024-04-28 |
| 2 | 2024-05-02 |
| 2 | 2024-05-03 |
| 2 | 2024-05-04 |
我们的目标是找出每个用户连续三天登录的所有数据记录,期望的输出结果如下:
| id | dt |
|---|---|
| 1 | 2024-04-25 |
| 1 | 2024-04-26 |
| 1 | 2024-04-27 |
| 1 | 2024-04-28 |
| 1 | 2024-04-30 |
| 1 | 2024-05-01 |
| 1 | 2024-05-02 |
| 2 | 2024-05-02 |
| 2 | 2024-05-03 |
| 2 | 2024-05-04 |
3. 查询思路
为了完成这个任务,我们可以利用 Hive SQL 的窗口函数来处理这个问题。主要的思路是:
- 窗口函数的使用:通过
LEAD()函数获取当前登录记录的下一天和下两天的日期。 - 日期差计算:计算当前日期和下一天、下两天的日期差,判断是否为连续的三天。
- 筛选符合条件的数据:最终筛选出满足条件(即连续三天登录)的数据记录。
4. 查询实现
下面是具体的 Hive SQL 查询实现:
with t as (select *, lead(dt,1,dt) over(partition by id order by dt) last_day, lead(dt,2,dt) over(partition by id order by dt) last_2_day from user_log
),
t2 as (select *, datediff(last_2_day, dt) date_diff from t
)
select distinct id, d
from t2
lateral view explode(map('dt', dt, 'last_day', last_day, 'last_2_day', last_2_day)) tem as s, d
where date_diff = 2;
5.代码解析
1. 子查询 t:
这个子查询为每个用户的登录记录添加了两列,分别是 last_day 和 last_2_day,它们表示当前记录的下一天和下两天的登录日期。这里使用了窗口函数 LEAD() 来实现。
LEAD(dt, 1, dt):这个窗口函数获取当前行的下一天登录日期。如果下一天不存在,则返回当前日期dt作为默认值。LEAD(dt, 2, dt):这个窗口函数获取当前行的下两天登录日期。如果下两天不存在,则返回当前日期dt作为默认值。PARTITION BY id:按id列(即用户ID)对数据进行分组。ORDER BY dt:按日期排序。
所以,t 子查询的结果将会如下(假设数据表 user_log 的某一部分):
| id | dt | last_day | last_2_day |
|---|---|---|---|
| 1 | 2024-04-25 | 2024-04-26 | 2024-04-27 |
| 1 | 2024-04-26 | 2024-04-27 | 2024-04-28 |
| 1 | 2024-04-27 | 2024-04-28 | 2024-04-30 |
| 1 | 2024-04-28 | 2024-04-30 | 2024-05-01 |
| 1 | 2024-04-30 | 2024-05-01 | 2024-05-02 |
| 1 | 2024-05-01 | 2024-05-02 | 2024-05-04 |
| 1 | 2024-05-02 | 2024-05-04 | 2024-05-05 |
2. 子查询 t2:
在 t2 子查询中,我们计算了日期差 date_diff,它表示 last_2_day 和当前登录日期 dt 之间的天数差。使用了 DATEDIFF() 函数来计算两个日期之间的天数差。
DATEDIFF(last_2_day, dt):计算last_2_day与当前日期dt之间的天数差。
date_diff 为 2 的记录说明 dt 与 last_2_day 是连续的三天登录。
3. LATERAL VIEW 和 EXPLODE:
在查询的外层,使用了 LATERAL VIEW 和 EXPLODE 来对数据进行展平操作,并对每个用户的连续三天登录日期进行处理。
LATERAL VIEW:LATERAL VIEW用于展开复杂数据类型(如数组或映射)。在这个查询中,LATERAL VIEW展开了一个映射(map),每个映射包含了dt、last_day和last_2_day三个字段。EXPLODE(map(...)):EXPLODE会将一个映射中的每个键值对展开为多行。对于每一行数据,都会根据映射的每个键值对创建一行记录。
map('dt', dt, 'last_day', last_day, 'last_2_day', last_2_day) 创建了一个映射(map),映射的键是 'dt'、'last_day' 和 'last_2_day',值分别是 dt、last_day 和 last_2_day。
这将会生成一个包含每个字段名(dt、last_day、last_2_day)和值的结果行。LATERAL VIEW 使得每一行的键值对都展开为多行数据,因此可以进一步进行查询操作。
4. 查询的最终条件:
最后,通过 where date_diff = 2 筛选出符合条件的记录。这意味着我们只选取那些连续三天登录的记录(日期差为 2),并通过 distinct 去重。
5. 查询结果示例
在执行查询后,我们将得到如下结果:
| id | dt |
|---|---|
| 1 | 2024-04-25 |
| 1 | 2024-04-26 |
| 1 | 2024-04-27 |
| 1 | 2024-04-28 |
| 1 | 2024-04-30 |
| 1 | 2024-05-01 |
| 1 | 2024-05-02 |
| 2 | 2024-05-02 |
| 2 | 2024-05-03 |
| 2 | 2024-05-04 |
这个结果显示了每个用户连续三天登录的记录,符合我们预期的输出。
相关文章:
【面试题】Hive 查询:如何查找用户连续三天登录的记录
1. 需求概述 在分析用户行为时,查询用户的连续登录数据是一个常见需求。例如,我们需要找出每个用户连续三天登录的记录。给定一个包含用户登录记录的表,我们需要对这些数据进行处理,提取出用户连续三天登录的日期。 2. 问题说明…...
高活跃社区 Doge 与零知识证明的强强联手,QED 重塑可扩展性
在 Web3 的广阔生态中,Doge 无疑是最具标志性和趣味性的项目之一。作为一种起源于网络文化的符号,Doge 从最初的互联网玩笑发展为如今备受全球关注的去中心化资产,依靠其独特的魅力和广泛的用户基础,构建了一个充满活力的社区。 …...
qt QAbstractTableModel详解
1、概述 QAbstractTableModel 是 Qt 框架中的一个类,用于在 Qt 应用程序中实现自定义的表格数据模型。它是 Qt 中的一个抽象基类,提供了创建和操作表格数据所需的接口。QAbstractTableModel 为模型提供了一个标准接口,这些模型将其数据表示为…...
掌握 Navicat 数据库结构设计 | 提升工作效率的秘诀
近期,我们介绍了 Navicat 17 的一系列的新特性,包括:兼容更多数据库、全新的模型设计、可视化 BI、智能数据分析、可视化查询解释、高质量数据字典、增强用户体验、扩展 MongoDB 功能、轻松固定查询结果、便捷 URI、支持更多平台等。今天&…...
Ollama AI 框架缺陷可能导致 DoS、模型盗窃和中毒
近日,东方联盟网络安全研究人员披露了 Ollama 人工智能 (AI) 框架中的六个安全漏洞,恶意行为者可能会利用这些漏洞执行各种操作,包括拒绝服务、模型中毒和模型盗窃。 知名网络安全专家、东方联盟创始人郭盛华表示:“总的来说&…...
vue 3:监听器
目录 1. 基本概念 2. 侦听数据源类型 1. 监听getter函数 2. 监听 ref 或 reactive 的引用 3. 多个来源组成的数组 4. 避免直接传递值!!! 3. 深层侦听器 4. 立即回调的侦听器 5. 一次性侦听器 6. watchEffect() 7. 暂停、恢复和停止…...
Java学习路线:Maven(四)Maven常用命令
在IDEA的Maven模块中,可以看到每个项目都有一个生命周期 这些生命周期实际上是Maven的一些插件,每个插件都有各自的功能,而双击这些插件就可以执行命令 这些命令的功能如下: clean:清除整个 target文件夹,…...
服务器数据恢复—分区结构被破坏的reiserfs文件系统数据恢复案例
服务器数据恢复环境: 一台服务器中有一组由4块SAS硬盘组建的RAID5阵列,上层安装linux操作系统统。分区结构:boot分区LVM卷swap分区(按照顺序),LVM卷中划分了一个reiserfs文件系统作为根分区。 服务器故障…...
lua入门教程:type函数
在Lua中,type 函数是一个内置函数,用于返回给定值的类型。Lua 支持多种数据类型,包括 nil(空值)、boolean(布尔值)、number(数字)、string(字符串)…...
Java图片转word
该方法可以控制一页是否只显示存放一张图片 第一步 <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.3</version></dependency><dependency><groupId>org.apache…...
立体视觉的核心技术:视差计算与图像校正详解
立体视觉的核心技术:视差计算与图像校正详解 在立体视觉中,通过双目相机(即左右两台相机)的不同视角捕获的图像,结合几何关系,我们可以推算出场景中物体的深度。本文将深入讲解如何基于视差(di…...
PaddleNLP的FAQ问答机器人
项目源码获取方式见文章末尾! 600多个深度学习项目资料,快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【DDRNet模型创新实现人像分割】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实…...
2024年12月中国多场国际学术会议,EI检索录用!
2024年12月,多场国际学术会议将在中国多地召开,涵盖AI、机器人、大数据、网络安全、传感制造、环境工程、物联网等领域,促进学术交流,录用论文将EI检索,诚邀国内外专家参会。 第三届人工智能、人机交互和机器人国际学…...
日语学习的难易程度
日语学习的难易程度是一个相对主观的问题,它受到多种因素的影响,包括个人的语言学习能力、学习方法、学习时间、学习资源的可获得性以及个人对日语文化的兴趣和投入程度等。以下是对日语学习难易程度的一些分析: 优点与易学之处 文字系统&am…...
java-web-web后端知识小结
spring框架三大核心: IOC--控制反转 DI---依赖注入 AOP--面向切面编程 web开发技术小结 1.过滤器,JWT令牌 2.三层架构 IOC, DI AOP, 全局异常处理, 事务管理 mybatis 3.数据操作与存储 mysql 阿里云OSS(云存储) 各个技术的归属: 1.过滤器, cookie,session--javaWeb 2.JWT, 阿里…...
常见的排序算法(二)
归并排序 归并排序(Merge Sort)是一种基于分治法(Divide and Conquer)的排序算法。它将一个大的问题分解成小的问题,然后递归地解决这些小问题,最后合并(merge)得到最终的排序结果。…...
spark的RDD分区的设定规则
目录 一、第一种:parallelize 获取rdd时 二、第二种:通过外部读取数据-textFile 三、上面提到了默认分区数,那么默认分区是怎么计算呢? 一、第一种:parallelize 获取rdd时 没有指定:spark.default.paral…...
【点云网络】voxelnet 和 pointpillar
VoxelNet 和 pointpillar 这两个网络可以认为后者是前者的升级版本,都是采用了空间划分的方法, 一个是体素,一个是pillar, 前者是3D卷积处理中间特征,后者是2D卷积处理中间特征。 voxelnet voxelnet 应该是比较早的onestage的网…...
HAL库硬件IIC驱动气压传感器BMP180
环境 1、keilMDK 5.38 2、STM32CUBEMX 初始配置 默认即可。 程序 1、头文件 #ifndef __BMP_180_H #define __BMP_180_H#include "main.h"typedef struct {float fTemp; /*温度,摄氏度*/float fPressure; /*压力,pa*/float fAltitude; /*…...
探索Python音频处理的奥秘:Pydub库的魔法
文章目录 探索Python音频处理的奥秘:Pydub库的魔法第一部分:背景介绍第二部分:Pydub是什么?第三部分:如何安装Pydub?第四部分:Pydub的简单函数使用方法1. 打开音频文件2. 播放音频3. 导出音频文…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
xmind转换为markdown
文章目录 解锁思维导图新姿势:将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件(ZIP处理)2.解析JSON数据结构3:递归转换树形结构4:Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...
在 Visual Studio Code 中使用驭码 CodeRider 提升开发效率:以冒泡排序为例
目录 前言1 插件安装与配置1.1 安装驭码 CodeRider1.2 初始配置建议 2 示例代码:冒泡排序3 驭码 CodeRider 功能详解3.1 功能概览3.2 代码解释功能3.3 自动注释生成3.4 逻辑修改功能3.5 单元测试自动生成3.6 代码优化建议 4 驭码的实际应用建议5 常见问题与解决建议…...
Python爬虫实战:研究Restkit库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的有价值数据。如何高效地采集这些数据并将其应用于实际业务中,成为了许多企业和开发者关注的焦点。网络爬虫技术作为一种自动化的数据采集工具,可以帮助我们从网页中提取所需的信息。而 RESTful API …...
Django RBAC项目后端实战 - 03 DRF权限控制实现
项目背景 在上一篇文章中,我们完成了JWT认证系统的集成。本篇文章将实现基于Redis的RBAC权限控制系统,为系统提供细粒度的权限控制。 开发目标 实现基于Redis的权限缓存机制开发DRF权限控制类实现权限管理API配置权限白名单 前置配置 在开始开发权限…...
