hive sql实战案例-访问开始结束时间

news2024/11/17 19:30:41

问题描述

现在我们有一张用户访问区域的记录表,有三个字段:user_id表示用户ID,area表示用户访问的区域,visit_time是访问时间。求用户对某一区域访问的开始和结束时间,结果如右表所示。
在这里插入图片描述

分析问题

101访问了上午和晚上分别访问了A,中文访问了B
102 早上9点访问了C,晚上19点也访问了C,总共访问了两次。
我们需要对同一用户访问相同地点的不同次做区分,然后聚合就好了
那我们定一个规则,如果用户换区域或者相邻两条记录间隔超过3小时,那么不算相同访问了。

准备数据

-- 删除表
drop table if exists visit;
-- 建表
CREATE TABLE visit (
  user_id bigint,
  area string,
  report_time string
);

-- 插入数据
INSERT overwrite table visit  
VALUES
  (101, 'A','2023-01-01 09:00:00'),
  (101, 'A','2023-01-01 10:00:00'),
  (101, 'B','2023-01-01 14:00:00'),
  (101, 'B','2023-01-01 15:00:00'),
  (101, 'A','2023-01-01 19:00:00'),
  (101, 'A','2023-01-01 20:00:00'),
  (102, 'C','2023-01-01 09:00:00'),
  (102, 'C','2023-01-01 10:00:00'),
  (102, 'C','2023-01-01 11:00:00'),
  (102, 'C','2023-01-01 19:00:00'),
  (102, 'C','2023-01-01 20:00:00');  
  
-- 查看数据
select * from visit

在这里插入图片描述

方案1:适用于换场+长间隔

1、取出每个用户的上一条访问记录的时间地点

select user_id
,report_time,area
,lag(area,1) over( partition by user_id order by report_time) as last_area
,lag(report_time,1) over( partition by user_id order by report_time) as last_time
from visit 

在这里插入图片描述
2、设置一个标识列,开始为0,其他为0

select t1.*
,case 
when last_area is null then 1  -- 没有访问
when last_area  !=area then 1  -- 换地方
when (unix_timestamp(report_time)-
        unix_timestamp(last_time))/(60*60)>=3 then 1  -- 超过3小时
when last_area = area then 0 end as num
from (
  select user_id
  ,report_time,area
  ,lag(area,1) over( partition by user_id order by report_time) as last_area
  ,lag(report_time,1) over( partition by user_id order by report_time) as last_time
  from visit 
) t1

在这里插入图片描述
3、使用sum over累计求和,给每次访问打标,相同访问标记一样

select t1.*
,sum(case 
when last_area is null then 1  -- 没有访问
when last_area  !=area then 1  -- 换地方
when (unix_timestamp(report_time)-
        unix_timestamp(last_time))/(60*60)>=3 then 1  -- 超过3小时
when last_area = area then 0 end)
over(partition by user_id order by report_time) as num
from (
  select user_id
  ,report_time,area
  ,lag(area,1) over( partition by user_id order by report_time) as last_area
  ,lag(report_time,1) over( partition by user_id order by report_time) as last_time
  from visit 
) t1

在这里插入图片描述
4、找到每个用户每个区域的首次末次访问时间

with t1 as (
  -- 上次访问记录
  select user_id
  ,report_time,area
  ,lag(area,1) over( partition by user_id order by report_time) as last_area
  ,lag(report_time,1) over( partition by user_id order by report_time) as last_time
  from visit 
)
,t2 as (
  -- 判断访问
     select *
    ,case 
    when last_area is null then 1  -- 没有访问
    when last_area  !=area then 1  -- 换地方
    when (unix_timestamp(report_time)-
            unix_timestamp(last_time))/(60*60)>=3 then 1  -- 超过3小时
    when last_area = area then 0 end as num
    from t1
)
,t3 as  (
  -- sum over 打标
   select user_id,area,report_time
   ,sum(num) over(partition by user_id order by report_time) as num
    from t2
  
)
-- 找到每个用户每个区域的起止时间
select user_id,area
,num 
,min(report_time) start_time
,max(report_time) end_time
from t3
group by user_id,area,num
-- order by user_id,start_time

在这里插入图片描述
实现了功能,感觉有点繁琐,抛转引玉吧!有好的方案,欢迎评论。

方案2:仅适用于换场

1、标记相同场地的不同访问。按用户编号减去按用户和场地编号,就可以找出换场次序,但是无法标记长时间间隔的,比如102上午、下午分别来了一次。

select user_id
,report_time,area
,row_number()over(partition by user_id order by report_time) as rn1 -- 按用户编码
,row_number()over(partition by user_id,area order by report_time) as rn2 -- 按用户和场地编码
-- rn1 -rn2就可以区分相同场的不同次
,row_number()over(partition by user_id order by report_time)-
row_number()over(partition by user_id,area order by report_time) as rn3 
from visit 
order by user_id,report_time

在这里插入图片描述
2、按照用户、场地和编码聚合,就可以找出起止时间了。A 是正常的,但C是不对的。

select user_id
,area
,rn3
,min(report_time) as start_time
,max(report_time) as end_time
from (
    select user_id
    ,report_time,area
    ,row_number()over(partition by user_id order by report_time) as rn1 -- 按用户编码
    ,row_number()over(partition by user_id,area order by report_time) as rn2 -- 按用户和场地编码
    -- rn1 -rn2就可以区分相同场的不同次
    ,row_number()over(partition by user_id order by report_time)-
    row_number()over(partition by user_id,area order by report_time) as rn3 
    from visit 
    order by user_id,report_time
) t1
group by  user_id
,area
,rn3

在这里插入图片描述

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

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

相关文章

InnoDB 与MyISAM 的区别

MyISAM和InnoDB都是Mysql里面的两个存储引擎。 在Mysql里面,存储引擎是可以自己扩展的,它的本质其实是定义数据存储的方式以及数据读取的实现逻辑。 不同存储引擎本身的特性,使得我们可以针对性的选择合适的引擎来实现不同的业务场景。从而获…

大数据框架-Hadoop

大数据框架-Hadoop 1.什么是大数据 大数据是指由传统数据处理工具难以处理的规模极大、结构复杂或速度极快的数据集合。这些数据集合通常需要使用先进的计算和分析技术才能够处理和分析,因此大数据技术包括了大数据存储、大数据处理和大数据分析等方面的技术和工具…

工作日记NO.2

1. 安装局域网内网通; 2. 安装VS2017AutoCADObjectARX VS2017AutoCAD2020配置ObjectARX VS2017AutoCAD2020配置ObjectARX (dgrt.cn) 3. ObjectARX简介 ObjectARX简介 - CAD安装教程 - 土木工程网 (civilcn.com) CAD系统二次开发-ObjectARX中的实体造型技术 (r…

【LeetCode】9,回文数。 难度等级:简单。巧妙解法很多,值得推敲。

文章目录 一、题目二、我的解答:逐个判断对应位置的首末数字是否相同三、其他解答3.1 将数字x转为字符串进行处理3.2 反转一半数字进行比较 LeetCode 第9题,回文数;难度等级:简单 一、题目 二、我的解答:逐个判断对应…

【C++复习1】程序结构和C++的工作原理

如果你是一名newbird的话,建议先看如下的视频加深理解后,再看下面的内容: https://www.bilibili.com/video/BV1N24y1B7nQ?p6 声明 以下的内容均由chatGpt编写与对上面这个视频进行总结生成,我就只负责改改格式。 C的工作原理 …

Live800:在线客服系统对客服管理有哪些好处?

互联网的不断发展,让越来越多的企业开始使用在线客服系统来提高客户服务质量。但是,很多人并不了解在线客服系统对客服管理的好处。本文将介绍在线客服系统的一些能够提高客服管理效率和提升用户满意度的管理功能。 实时客服监控 在线客服系统可以实时监…

MPU6050详解(含源码)

前言:MPU6050是一款强大的六轴传感器,需要理解MPU6050首先得有IIC的基础,MPU6050 内部整合了 3 轴陀螺仪和 3 轴加速度传感器,并且含有一个第二 IIC 接口,可用于连接外部磁力传感器,内部有硬件算法支持. 1…

JumpServer Harbor

Jumpserver是一款开源的堡垒机,可使系统的管理员和开发人员安全的连接到企业内部服务器上执行操作,并且支持大部分操作系统,是一款非常安全的远程连接工具 安装JumpServer jumpserver.org官网去下载安装,有一键安装(里…

【回溯篇(3)---最少城市数】

1、最少城市数 【题目】 下图表示的是从城市A到城市H的交通图。从图中可以看出,从城市A到城市H要经过若干个城市。现要找出一条经过城市最少的一条路线。 【算法分析】 看到这图很容易想到用邻接距阵来表示,0表示能走,1表示不能走。如图。…

BM14 链表的奇偶重排

链表的奇偶重排_牛客题霸_牛客网 (nowcoder.com) 双指针解决 /*** struct ListNode {* int val;* struct ListNode *next;* ListNode(int x) : val(x), next(nullptr) {}* };*/ class Solution { public:/*** 代码中的类名、方法名、参数名已经指定,请勿修改&#x…

Android 9.0 系统systemui状态栏下拉左滑显示通知栏右滑显示控制中心模块的流程分析

1.前言 在android9.0的系统rom定制化开发中,在系统原生systemui进行自定义下拉状态栏布局的定制的时候,需要在systemui下拉状态栏下滑的时候,根据下滑坐标来 判断当前是滑出通知栏还是滑出控制中心模块,所以就需要根据屏幕宽度,来区分x坐标值为多少是左滑出通知栏或者右…

Linux_红帽8学习笔记分享_9(文件系统管理FS Management与swap交换分区管理)

Linux_红帽8学习笔记分享_9(文件系统管理FS Management与swap交换分区管理) 文章目录 Linux_红帽8学习笔记分享_9(**文件系统管理FS Management与swap交换分区管理**)1.fdisk分区命令的使用技巧1.1 创建大小为100M,200M,300M,400M,500M的5个磁盘分区(MBR分区表类型)1.2创建大小…

固态继电器的优点

固态继电器的优点包括紧凑性、抗冲击性和长寿命。以下是这些 SSR 优势中最重要的优势,让您了解为什么这项技术最适合您的应用: 开关速度快 固态继电器器件的主要优点之一是其开关速度。由于无需移动机械部件,SSR 可以在几微秒内切换。这是对…

详解MySQL慢SQL定位、分析

目录 1.概述 2.慢SQL定位 3.SQL性能分析 3.1.例子 3.2.SQL性能分析 3.3.参数说明 3.3.1.id 3.3.2.select_type 3.3.3.key_len 3.3.4.rows 3.3.5.type 3.3.6.extra 1.概述 解决慢SQL的问题无非散步,定位慢SQL、分析慢SQL、优化慢SQL,本文将按…

高效提升计算质量!瑞典量子计算机首次应用于化学

​ (图片来源:网络) 量子计算机可以模拟化学过程,从新药开发到新材料的方方面面,它都能带来重大影响,人们对此寄予厚望。在瑞典,查尔姆斯理工大学的研究人员首次使用量子计算机在实际化学中进行…

PyQt5桌面应用开发(9):经典布局QMainWindow

本文目录 PyQt5桌面应用系列桌面程序基本布局QMainWindow概况与使用主窗体菜单栏工具栏停靠窗状态栏 代码编辑器的例子总结 PyQt5桌面应用系列 PyQt5桌面应用开发(1):需求分析 PyQt5桌面应用开发(2):事件循…

113-Linux_安装c/c++开发库及连接mysql数据库

文章目录 一.安装c/c开发库二.连接mysql数据库三.用户的管理与授权 mysql数据库的安装 一.安装c/c开发库 安装开发c/c的库&#xff0c;命令&#xff1a;apt install libmysqlclient-dev 二.连接mysql数据库 #include<stdio.h> #include<mysql/mysql.h>void fun…

JAVA13新特性

JAVA13新特性 概述 2019年9月17日&#xff0c;国际知名的OpenJDK开源社区发布了Java编程语言环境的最新版本OpenJDK13。 Features&#xff1a;总共有5个新的JEP(JDK Enhancement Proposals): http://openjdk.java.net/projects/jdk/13/Features 350:Dynamic CDS Archives 动…

C++ STL之vector基础

文章目录 前言STL之vector基础1. What&#xff1a;什么是 vector&#xff1f;2. Why&#xff1a;为什么使用 vector&#xff1f;3. How&#xff1a;怎么使用vector?3.1 vector的定义演示&#xff1a;输出&#xff1a; 3.2 vector iterator 的使用演示&#xff1a;输出&#xf…

网络基础学习:什么是tcp/ip协议

什么是tcp/ip协议 TCP/ip协议是什么东西&#xff1f;tcp/ip四层模型一、应用层二、传输层三、网络层四、网络接口层 TCP/ip协议是什么东西&#xff1f; TCP/IP是一种网络协议套件&#xff0c;它由传输控制协议&#xff08;TCP&#xff09;和互联网协议&#xff08;IP&#xff…