首页 > 数据库 >HIVE SQL 高频(持续更新)

HIVE SQL 高频(持续更新)

时间:2024-08-26 15:51:02浏览次数:14  
标签:SQL HIVE user time table 高频 id SELECT rk

整理自数据分析常考面试题100题

1. 连续日期

1、为日期排序
 row_number() over (partition by use_id order by date) as rank

2、求日期和排序的差值

3、求 diff 出现最多的次数 max(count(diff))

例1:

- 每个用户一周活跃天数 -
SELECT user_id,
       COUNT(1) AS active_day
FROM (SELECT user_id, date 
      FROM table
      WHERE TIMESTAMPDIFF(DAY,date,CURRENT_DATE) <= 7
      GROUP BY user_id, date) a  -- 这里还要加GROUP BY date是为了去重 --
GROUP BY user_id;

- 每个用户一周内最大连续活跃天数 -
WITH recent_day AS(
SELECT user_id, date
FROM table
WHERE TIMESTAMPDIFF(DAY, date, CURRENT_DATE) <= 7
GROUP BY user_id, date
),
diff_table AS(
SELECT user_id,
       ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY date) AS rank,
       DATE_SUB(date, ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY transdt)) AS gap
       -- 连续活跃的话,gap会一样 -- 
       FROM recent_day
),
gap_cnt AS(
SELECT user_id, count(gap) AS count
FROM diff_table
GROUP BY user_id, gap
)
SELECT user_id, MAX(count)
FROM gap_cnt
GROUP BY user_id

* TIMESTAMPDIFF(unit, start, end) ; DATEDIFF(end, start)

例2:

- 截至当前,每个用户已经连续签到的天数 - 
SELECT user_id,
DATEDIFF(CURRENT_DATE, no_sign_in) AS consecutive_days
FROM (SELECT user_id, MAX(date) AS no_sign_in
      FROM table
      WHERE is_sign_in = 0
      GROUP BY user_id
      ) 

思路:找到最近的“中断”点:找到最近一次没有签到的日期,那么在这之后的所有天数都可以被视为连续签到的天数。

2.时间间隔问题

1. 为日期排序

row number() over(partition by id order by date) as rank

2、错位相减,来实现“相邻” 要求, 求日期和排序的差值( diff)

3、根据题目要求,求出相应指标· max(时间差)· count(*) · min(时间差)

- 每个用户相邻两次浏览时间之差小于 3min 的次数 - 
WITH rank_table AS(
SELECT user_id, user_time,
       ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY user_time) AS rk
FROM table 
),
misaligned_sub AS(
SELECT user_id, a.user_time, b.user_time
FROM rank_table a
JOIN rank_table b ON a.user_id = b.user_id AND a.rk = b.rk - 1
)
SELECT user_id, COUNT(1) AS times
FROM misaligned_sub
WHERE TIMESTAMPDIFF(MINUTE, a.user_time, b.user_time) <= 3
GROUP BY user_id

延申:同一个用户购买同一个商品相邻两次的时间间隔

-同一个用户购买同一个商品相邻两次的时间间隔-
WITH ranked_purchases AS (
    SELECT user_id, 
           product_id, 
           purchase_time, 
           ROW_NUMBER() OVER (PARTITION BY user_id, product_id ORDER BY purchase_time) AS rk
    FROM purchases_table
)
SELECT a.user_id, 
       a.product_id, 
       a.purchase_time AS current_purchase_time, 
       b.purchase_time AS next_purchase_time,
       TIMESTAMPDIFF(MINUTE, b.purchase_time, a.purchase_time) AS time_interval_minutes
FROM ranked_purchases a
JOIN ranked_purchases b 
ON a.user_id = b.user_id 
   AND a.product_id = b.product_id 
   AND a.rk = b.rk - 1;

3. 求累加

SELECT user_id, 
       date, 
       amount, 
       SUM(amount) OVER (PARTITION BY user_id ORDER BY date) AS cumulative_amount
FROM table
  • ROWS BETWEEN: 基于行的位置来定义窗口帧,精确匹配行。
  • RANGE BETWEEN: 基于值范围来定义窗口帧,可能包含具有相同排序值的多行。range表示的是 具体的值,比这个值小n的行,比这个值大n的行
  • sum(close) range between 100 preceding and 200 following: 如当前行的 close 字段值是 200,那么这个窗口大小的定义就会选择分区中 close 字段值落在 100 至 400 区间的记录(行)。

unbounded preceding 前面所有行

unbounded following 后面所有行

current row 当前行

n following 后面n行

n preceding 前面n行

4. LEAD and LAG

lag :用于统计窗口内往上第 n 行值

lead :用于统计窗口内往下第 n 行值

lag 和 lead 有三个参数,第一个参数是列名,第二个参数是偏移量,第三个参数是超出记录窗口时的默认值

例1:有三列user,time和url,获取用户在某个页面停留时长

SELECT userid, url,
       UNIX_TIMESTAMP(LEAD(time,1) OVER(PARTITION BY userid ORDER BY time)) - UNIX_TIMESTAMP(time) AS period
FROM user_log

例2:寻找至少连续出现 3 次的数字

SELECT DISTINCT num
FROM (SELECT 
        num,
        LAG(num,1) OVER() AS lag1,
        LAG(num,2) OVER() AS lag2
      FROM table
      ) a
WHERE num = lag1 AND num = lag2

5.行/列转换

多行转一行:

SELECT Product,
CONCAT_WS(',',COLLECT_SET(Supplier)) AS Supplier
FROM mytable
GROUP BY Product

*collect_set 函数,有两个作用,第一个是去重,去除 group by 后的重复元素,第二个是形成一个集合,将 group by 后属于同一组的集合起来成为一个集合。

一行转多行:

SELECT Product, Supplier
FROM mytable
LATERAL VIEW EXPLODE(SPLIT(Supplier,',')) tb1 AS Supplier

6.去除最高最低的平均

计算除去部门最高工资,和最低工资的平均工资(字节跳动面试)

SELECT a.Department, AVG(a.Salary) AS avg_salary
FROM (
    SELECT 
        Department,
        Salary,
        RANK() OVER(PARTITION BY Department ORDER BY Salary ASC) AS asc_rk,
        RANK() OVER(PARTITION BY Department ORDER BY Salary DESC) AS desc_rk
    FROM Salary_Info
) a
WHERE a.asc_rk > 1  -- 去除最低的薪资
  AND a.desc_rk > 1 -- 去除最高的薪资
GROUP BY a.Department;

核心是使用窗口函数 RANK 分别对工资 salary 进行升序和降序排列,就获得了该分组内最低和最高的工资,过滤掉这 2 条记录

rank()排序相同时会重复,总数不变,即会出现1、1、3这样的排序结果;

dense_rank()排序相同时会重复,总数会减少,即会出现1、1、2这样的排序结果;

标签:SQL,HIVE,user,time,table,高频,id,SELECT,rk
From: https://blog.csdn.net/m0_63190465/article/details/141529972

相关文章

  • MySQL-基础篇
    MySQL概述1、数据库相关概念主流的关系型数据库:总结1)数据库:数据存储的仓库2)数据库管理系统:操纵和管理数据库的大型软件3)SQL:操作关系型数据库的编程语言,是一套标准2、MySQL数据库版本MySQL官方提供了两种不同的版本:社区版(MySOLCommunityServer)=>免费,MySQL......
  • MySQL常用的分组聚合函数
    一、聚合函数(aggregationfunction)---也就是组函数在一个行的集合(一组行)上进行操作,对每个组给一个结果。常用的组函数:AVG([distinct]expr)求平均值COUNT({*|[distinct]}expr)统计行的数量MAX([distinct]expr)求最大值MIN([distinct]exp......
  • Flink系列-SQL connector扩展以及DataGenTableSourceFactory源码走读
    一、说明    通常我们直接使用Flink的sql进行实时任务开发,经常会遇到扩展新的数据源端或者目标端的场景,或者需要了解connector的一些源码机制,方便开发和定位问题。    如何扩展新增Sqlconnector呢?扩展ApacheFlink的新SQLConnector主要涉及以下几个步骤:......
  • SparkSQL日期时间模式详解
    datatime使用场景CSV/JSON数据源使用模式字符串来解析和格式化日期时间内容。日期时间函数用于转换StringType类型到DateType或TimestampType类型,反之亦然。例如,unix_timestamp,date_format,to_unix_timestamp,from_unixtime,to_date,to_timestamp,from_utc_timestam......
  • SparkSQL数值模式详解
    简介函数如to_number和to_char确实支持在字符串类型和十进制(数值)类型之间进行转换。这些函数接受格式字符串作为参数,这些格式字符串指示了如何在这两种类型之间映射。to_number:这个函数通常用于将字符串转换成数值类型。你需要提供一个格式字符串来指定如何解释字符串......
  • MySQL的 索引名 ,不同的表 可以 同一个索引名吗
    在MySQL中,不同的表可以使用相同的索引名。MySQL的索引名是在表级别定义的,这意味着索引名的作用域限定于其所属的表。因此,即使两个或多个表拥有相同名称的索引,也不会引起冲突,因为MySQL会根据表名和索引名的组合来唯一标识索引。例如,如果你有两个表users和products,并且你想在这两个......
  • 代码训练营 Day11 | 150. 逆波兰表达式求值 | 239. 滑动窗口最大值 | 347.前 K 个高频
    150.逆波兰表达式求值逆波兰表达式(后缀表达式)(1+2)x(3+4)的后续表达顺序是:左右中 后缀表达式:12+34+x使用栈思路1.遇见数字就放入栈,遇见操作运算符,取出栈里的数字进行运算2.每次取元素的时候只取两个元素3.结果就是栈最后的元素classSolution(object):d......
  • 免费分享一套Java协同过滤推荐算法的SpringBoot+Vue(图书)商城系统【论文+源码+SQL脚
    大家好,我是java1234_小锋老师,看到一个不错的Java协同过滤推荐算法的SpringBoot+Vue(图书)商城系统,分享下哈。项目视频演示【免费】Java协同过滤推荐算法的SpringBoot+Vue(图书)商城系统Java毕业设计_哔哩哔哩_bilibili项目介绍伴随着Internet的蓬勃发展,电子商务也取得了......
  • 利用python连接MySQL数据库
    利用python连接MySQL数据库1、准备工作:(1)事先在系统中已经安装好mysql数据库(2)在系统控制台通过pipinstallpymysql,安装python的第三方数据库模块2、利用python连接数据库#导入模块importpymysql#连接数据库conn=pymysql.connect(host="127.0.0.1",user="root",pas......
  • 在 SQLAlchemy 中实现数据处理的时候,实现表自引用、多对多、联合查询,有序id等常见的一
    有时候,我们在使用SQLAlchemy操作某些表的时候,需要使用外键关系来实现一对多或者多对多的关系引用,以及对多表的联合查询,有序列的uuid值或者自增id值,字符串的分拆等常见处理操作。1、在SQLAlchemy中定义具有嵌套children关系的表要在SQLAlchemy中定义具有嵌套children关系......