解决问题:hive中count(distinct ) over() 无法使用场景

累计去除统计,实际经常使用到的场景比如会员每日历史累计消费,项目每日累计营收等。

案例:

数据准备:

用户轨迹用户访问日志表 test_visit_tab

cookieid(用户id) uvdate(访问时间) pagename(浏览页面) pv(访问次数)
cookie1 2022-02-01  A_page  1
cookie1 2022-02-01  B_page  2
cookie1 2022-02-02  A_page  1
cookie1 2022-02-02  B_page  3
cookie2 2022-02-01  A_page  1
cookie2 2022-02-01  B_page  5
cookie2 2022-02-03  A_page  2
cookie3 2022-02-02  A_page  6
cookie3 2022-02-02  B_page  3
cookie3 2022-02-03  A_page  1
cookie3 2022-02-03  B_page  2
cookie3 2022-02-04  A_page  1
cookie3 2022-02-04  B_page  5
cookie4 2022-02-05  A_page  1
cookie4 2022-02-05  B_page  4

需要统计的效果按照uvdate时间统计截止当前访问人数,统计效果

uvdate uv(当天uv) add_uv(截止当天uv)
2022-02-01  2   2
2022-02-02  2   3
2022-02-03  2   3
2022-02-04  1   3
2022-02-05  1   4

开窗count(distinct )over(order by)尝试

select uvdate
,count(distinct cookieid) as uv
-- order by 开窗截止数据
,count(distinct cookieid)over(order by uvdate) as add_uv
from test_visit_tab
group by uvdate

最终出来的结果

uvdate uv add_uv
2022-02-01  2   2
2022-02-02  2   2
2022-02-03  2   2
2022-02-04  1   1
2022-02-05  1   1

方法一:

发现虽然语法可以通过查询,但是结果其实和coount(distinct cookieid)不开窗的效果一致,换个思路使用sum开窗处理

思路:

1、将用户按照日期排序

2、统计每日新增用户(排序为1的值求和)

3、计算每日累计新增用户求和

实现:

select uvdate
,uv
,sum(add_uv_num)over(order by uvdate) as add_uv
from (
    select uvdate
    ,count(distinct cookieid) as uv
    -- 每日只统计新增用户()
    ,sum(case when rankid = 1 then 1 else 0 end) as add_uv_num
    from (
        select uvdate,cookieid
        -- 将用户访问按时间排序
        ,row_number()over(partition by cookieid order by uvdate asc) as rankid
        from test_visit_tab
        group by uvdate,cookieid
    ) as tab_1
    group by uvdate
) as tab_2

最终结果:

uvdate uv add_uv
2022-02-01  2   2
2022-02-02  2   3
2022-02-03  2   3
2022-02-04  1   3
2022-02-05  1   4

方法二:

使用collect_set聚合函数后再size()求长度,实现去重统计的效果,弊端collect_set开窗后无法进行去重操作(后面可以再查看group内容)

实现:

select distinct uvdate,add_uv
from (
    select uvdate
    ,size(collect_set(cookieid)over(order by uvdate)) as add_uv
    from test_visit_tab
) as tt

最终结果:

uvdate add_uv
2022-02-01  2
2022-02-02  3
2022-02-03  3
2022-02-04  3
2022-02-05  4

阐述上述两种方法解决count distinct无法统计问题和解决部分实际场景统计方式,开窗具体语法可以查看。

hive 开窗函数OVER(PARTITION)详解(一)_liuya19921123的博客-CSDN博客_hive的over partition什么是窗口函数?窗口函数(Window Function)是 SQL2003 标准中定义的一项新特性,并在 SQL2011、SQL2016 中又加以完善,添加了若干处拓展。窗口函数不同于我们熟悉的普通函数和聚合函数,它为每行数据进行一次计算:输入多行(一个窗口)、返回一个值。在报表等分析型查询中,窗口函数能优雅地表达某些需求,发挥不可替代的作用。窗口函数出现在 SELECT 子句的表达式列表中,它最显著的特点就是OVER关键字。语法定义如下:window_function (expres...https://blog.csdn.net/liuya19921123/article/details/120430584hive 开窗函数OVER(PARTITION)详解(二)_liuya19921123的博客-CSDN博客_hive over 开窗函数窗口函数有哪些?窗口函数可以分为以下 3 类:聚合(Aggregate):AVG(),COUNT(),MIN(),MAX(),SUM()...sum(col) over() : 分组对col累计求和 count(col) over() : 分组对col累计计数 min(col) over() : 分组对col求最小 max(col) over() : 分组求col的最大值 avg(col) over() : 分组求col列的平均值取值(Value):FIRST_VALUE(),LAS...https://blog.csdn.net/liuya19921123/article/details/120511937

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐