• Hive中抽取连续多天登录用户


    昨天群上有人发个阿里的面试题,题目描述大概如下:

    数据源:用户登录表,只有俩个字段,uid和dt

    试用HQL抽取出连续登录了K天的用户uid

    第一个想法就是直接用一个UDF解决,按uid分组,把dt收集起来然后在UDF里面判断是否满足条件

    SELECT
        uid,
        isExist(collect_set(dt), k) flag
    FROM
        table_name
    GROUP BY
        uid
    HAVING
        flag = 1;

    其中isExist的逻辑是判断collect_set中是否存在k个连续的值

    这种方法简单明了,但是需要额外的写一个UDF,对于不懂JAVA的来说确实比较麻烦

    今天群里有个神人给出了一种新的解决思路,十分完美的解决了,下面是具体代码

    SELECT 
        uid, MAX(dt) - MIN(dt) diff, COLLECT_set (dt) 
    FROM
        (SELECT 
            a.uid, a.dt, dt - rn num 
        FROM
            (SELECT 
                uid, dt, row_number () over (PARTITION BY uid 
            ORDER BY dt) rn 
            FROM
                table_name
            GROUP BY uid, dt) a) a 
    GROUP BY uid, num 

    该思路首先利用窗口函数以uid分组然后按照dt排序给出每个dt在排序中的位置,然后用求出dt与位置的差(记为num)

    最后按照uid和num做一个聚合,容易发现同一个num组内的dt是连续的值

    然后直接计数(count(*))就可以得出结果了

    上面的代码只是为了更加方便看到输出的结果正确性,输出结果如下:

    UID        DIFF    DT_ARRAY
    1043736    3.020140815    20140814    20140813    201408121043736    0.0201408181043736    1.020140821    201408201043844    0.0201408141044090    1.020140812    201408111044090    2.020140816    20140815    201408171044090    0.0201408211044264    0.0201408101044264    3.020140815    20140814    20140813    201408121044264    5.020140821    20140820    20140822    20140819    20140817    20140818

    结果中uid = 1043736 的一共登录了7天,其中可以拆分成三个连续的登录模块,分别是连续登录1天、2天和4天

        
  • 相关阅读:
    SpringMVC——拦截器及文件上传和下载
    SpringMVC——数据处理
    SpringMVC——返回结果及指定视图
    SpringMVC——SpringMVC配置
    SpringMVC——简介及原理简单分析
    Kakfa和其他类型消息中间件对比图
    Kafka消费者——结合spring开发
    Kafka生产者——结合spring开发
    五大浏览器-四大内核
    python中查看module和function的方法
  • 原文地址:https://www.cnblogs.com/juefan/p/3928966.html
Copyright © 2020-2023  润新知