HiveSQL——用户中两人一定认识的组合数

2024-02-09 18:12

本文主要是介绍HiveSQL——用户中两人一定认识的组合数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

注:参考文章:

SQL之用户中两人一定认识的组合数--HQL面试题36【快手数仓面试题】_sql面试题-快手-CSDN博客文章浏览阅读1.2k次,点赞3次,收藏12次。目录0 需求分析1 数据准备2 数据分析3 小结0 需求分析设表名:table0现有城市网吧访问数据,字段:网吧id,访客id(身份证号),上线时间,下线时间规则1、如果有两个用户在一家网吧的前后上下线时间在10分钟以内,则两人可能认识规则2、如果这两个用户在三家以上网..._sql面试题-快手https://blog.csdn.net/godlovedaniel/article/details/119155757

0 问题描述

     现有一张表table21, 里面装载城市网吧访问数据,字段:网吧id, 访客id(身份证号),上线时间、下线时间

     规则1:如果有两个用户在一家网吧的前后上线时间在10分钟内,则两人可能认识;

     规则2:如果这两个用户在三家以上网吧出现【规则1】的情况,则两人一定认识

  需求:该城市上网用户中两人一定认识的组合数

1 数据准备

create table table21(wid string,uid string,ontime string,offtime string
)
row format delimited fields terminated by '\t';insert overwrite table table21 values(1,110001,'2020-01-01 11:10:00','2020-01-01 11:15:00')
,(1,110001,'2020-01-01 11:18:00','2020-01-01 11:23:00')
,(1,110002,'2020-01-01 12:10:00','2020-01-01 13:15:00')
,(1,110001,'2020-01-01 12:11:00','2020-01-01 13:10:00')
,(1,110003,'2020-01-01 12:15:00','2020-01-01 13:15:00')
,(1,110004,'2020-01-01 12:16:00','2020-01-01 13:18:00'),(2,110001,'2020-01-02 12:10:00','2020-01-02 12:30:00')
,(2,110001,'2020-01-02 12:50:00','2020-01-02 13:05:00')
,(2,110002,'2020-01-02 12:52:00','2020-01-02 12:55:00')
,(2,110003,'2020-01-02 12:58:00','2020-01-02 13:20:00')
,(2,110004,'2020-01-02 13:00:00','2020-01-02 13:10:00'),(3,110001,'2020-01-03 12:10:00','2020-01-03 12:30:00')
,(3,110003,'2020-01-03 12:55:00','2020-01-03 13:02:00')
,(3,110001,'2020-01-03 12:50:00','2020-01-03 12:55:00')
,(3,110002,'2020-01-03 13:00:00','2020-01-03 13:01:00')
,(3,110004,'2020-01-03 12:58:00','2020-01-03 13:03:00')
,(3,110002,'2020-01-03 13:20:00','2020-01-03 13:25:00');

2  数据分析

     根据规则1和规则2,求城市上网用户中两人一定认识的组合数,就是指两两相识的组合数。对于这种两两组合数一般用自关联,通过自关联将尽可能的情况表示出来,然后按照条件筛选数据

    step1:表自关联计算,得到所有相遇的情况:(笛卡尔积)

select *
from table21 as t0
join table21 as t1;

    step2:根据规则1,得出可能的结果:

 selectt0.wid as t0_wid,t0.uid as t0_uid,t1.wid as t1_wid,t1.uid as t1_uidfrom table21 as t0join table21 as t1where t0.wid = t1.widand (abs(unix_timestamp(t0.ontime, 'yyyy-MM-dd HH:mm:ss')- unix_timestamp(t1.ontime, 'yyyy-MM-dd HH:mm:ss')) < 600 orabs(unix_timestamp(t0.offtime, 'yyyy-MM-dd HH:mm:ss')- unix_timestamp(t1.offtime, 'yyyy-MM-dd HH:mm:ss')) < 600)and t0.uid > t1.uid

上述代码用到的函数:

unix_timestamp(日期转时间戳函数)
语法:unix_timestamp(string date)  、unix_timestamp(string date,string pattern)
返回值:bigint
说明:将格式为"yyyy-MM-dd HH:mm:ss"的日期 转换成 unix的时间戳。如果转换失败,则返回值为0;
举例:select unix_timestamp('20240201 20:17:11','yyyyMMdd HH:mm:ss')  --> 1706825843

 abs(unix_timestamp(t0.ontime, 'yyyy-MM-dd HH:mm:ss')  - unix_timestamp(t1.ontime, 'yyyy-MM-dd HH:mm:ss')) < 600  代表的意思是:两个用户在一家网吧的前后上线时间在10分钟内(10分钟也就是600秒)

   ps: 需要将同一网吧中可能两两相识的人筛选出来,所以【用户A、用户B】 与【用户B、用户A】 实际上是一样的,只需要选出 t0.uid > t1.uid 即可(去重取一)

step3:根据step2,可以将同一网吧中可能两两相识的人筛选出来,将互相认识的人组合成一个key,通过该key来判断该两人是否满足规则2。具体sql如下:

 selectt0_wid,-- 将可能互相认识的人的uid拼接起来,组成key值(uuid)concat_ws('~', t0_uid, t1_uid) as uuid
from (selectt0.wid as t0_wid,t0.uid as t0_uid,t1.wid as t1_wid,t1.uid as t1_uidfrom table21 as t0join table21 as t1where t0.wid = t1.widand (abs(unix_timestamp(t0.ontime, 'yyyy-MM-dd HH:mm:ss')- unix_timestamp(t1.ontime, 'yyyy-MM-dd HH:mm:ss')) < 600 orabs(unix_timestamp(t0.offtime, 'yyyy-MM-dd HH:mm:ss')- unix_timestamp(t1.offtime, 'yyyy-MM-dd HH:mm:ss')) < 600)and t0.uid > t1.uid) t2

step4:对【两人一定认识】记录进行打标签,记为 1

selectuuid,-- 对【两人一定认识】记录进行打标签,记为 1if(count(t0_wid) >=3,1,0) as flagfrom
(selectt0_wid,-- 将可能互相认识的人的uid拼接起来,组成key值(uuid)concat_ws('~', t0_uid, t1_uid) as uuid
from (selectt0.wid as t0_wid,t0.uid as t0_uid,t1.wid as t1_wid,t1.uid as t1_uidfrom table21 as t0join table21 as t1where t0.wid = t1.widand (abs(unix_timestamp(t0.ontime, 'yyyy-MM-dd HH:mm:ss')- unix_timestamp(t1.ontime, 'yyyy-MM-dd HH:mm:ss')) < 600 orabs(unix_timestamp(t0.offtime, 'yyyy-MM-dd HH:mm:ss')- unix_timestamp(t1.offtime, 'yyyy-MM-dd HH:mm:ss')) < 600)and t0.uid > t1.uid) t2
)t3
group by  uuid;

step4:计算满足规则1和规则2的记录总数,得出结果为6条

selectcount(1) as cnt
from (selectuuid,-- 对【两人一定认识】记录进行打标签,记为 1if(count(t0_wid) >= 3, 1, 0) as flagfrom (selectt0_wid,-- 将可能互相认识的人的uid拼接起来,组成key值(uuid)concat_ws('~', t0_uid, t1_uid) as uuidfrom (selectt0.wid as t0_wid,t0.uid as t0_uid,t1.wid as t1_wid,t1.uid as t1_uidfrom table21 as t0join table21 as t1where t0.wid = t1.widand (abs(unix_timestamp(t0.ontime, 'yyyy-MM-dd HH:mm:ss')- unix_timestamp(t1.ontime, 'yyyy-MM-dd HH:mm:ss')) < 600 orabs(unix_timestamp(t0.offtime, 'yyyy-MM-dd HH:mm:ss')- unix_timestamp(t1.offtime, 'yyyy-MM-dd HH:mm:ss')) < 600)and t0.uid > t1.uid) t2) t3group by uuid) t4;

3 小结  

   本案例题型属于:“共同xx”,例如:共同好友、互相认识、共同使用等。遇到这类关键字的时候,往往可以采用自关联的方式解决。(笛卡尔积:“一对多”或者“ 多对一”),一般的解题步骤就是:通过自关联将所有的组合求解出来,然后将符合条件的数据进行过滤即可。

这篇关于HiveSQL——用户中两人一定认识的组合数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Java对异常的认识与异常的处理小结

《Java对异常的认识与异常的处理小结》Java程序在运行时可能出现的错误或非正常情况称为异常,下面给大家介绍Java对异常的认识与异常的处理,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参... 目录一、认识异常与异常类型。二、异常的处理三、总结 一、认识异常与异常类型。(1)简单定义-什么是

Mysql中的用户管理实践

《Mysql中的用户管理实践》:本文主要介绍Mysql中的用户管理实践,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录13. 用户管理13.1 用户 13.1.1 用户信息 13.1.2 创建用户 13.1.3 删除用户 13.1.4 修改用户

详解如何在SpringBoot控制器中处理用户数据

《详解如何在SpringBoot控制器中处理用户数据》在SpringBoot应用开发中,控制器(Controller)扮演着至关重要的角色,它负责接收用户请求、处理数据并返回响应,本文将深入浅出地讲解... 目录一、获取请求参数1.1 获取查询参数1.2 获取路径参数二、处理表单提交2.1 处理表单数据三、

CentOS和Ubuntu系统使用shell脚本创建用户和设置密码

《CentOS和Ubuntu系统使用shell脚本创建用户和设置密码》在Linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设置密码,本文写了一个shell... 在linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设

SpringBoot UserAgentUtils获取用户浏览器的用法

《SpringBootUserAgentUtils获取用户浏览器的用法》UserAgentUtils是于处理用户代理(User-Agent)字符串的工具类,一般用于解析和处理浏览器、操作系统以及设备... 目录介绍效果图依赖封装客户端工具封装IP工具实体类获取设备信息入库介绍UserAgentUtils

Mysql用户授权(GRANT)语法及示例解读

《Mysql用户授权(GRANT)语法及示例解读》:本文主要介绍Mysql用户授权(GRANT)语法及示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql用户授权(GRANT)语法授予用户权限语法GRANT语句中的<权限类型>的使用WITH GRANT

mysql删除无用用户的方法实现

《mysql删除无用用户的方法实现》本文主要介绍了mysql删除无用用户的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 1、删除不用的账户(1) 查看当前已存在账户mysql> select user,host,pa

TP-Link PDDNS服将于务6月30日正式停运:用户需转向第三方DDNS服务

《TP-LinkPDDNS服将于务6月30日正式停运:用户需转向第三方DDNS服务》近期,路由器制造巨头普联(TP-Link)在用户群体中引发了一系列重要变动,上个月,公司发出了一则通知,明确要求所... 路由器厂商普联(TP-Link)上个月发布公告要求所有用户必须完成实名认证后才能继续使用普联提供的 D

Oracle数据库如何切换登录用户(system和sys)

《Oracle数据库如何切换登录用户(system和sys)》文章介绍了如何使用SQL*Plus工具登录Oracle数据库的system用户,包括打开登录入口、输入用户名和口令、以及切换到sys用户的... 目录打开登录入口登录system用户总结打开登录入口win+R打开运行对话框,输php入:sqlp

数据库oracle用户密码过期查询及解决方案

《数据库oracle用户密码过期查询及解决方案》:本文主要介绍如何处理ORACLE数据库用户密码过期和修改密码期限的问题,包括创建用户、赋予权限、修改密码、解锁用户和设置密码期限,文中通过代码介绍... 目录前言一、创建用户、赋予权限、修改密码、解锁用户和设置期限二、查询用户密码期限和过期后的修改1.查询用