大数据场景下使用SQL求UV和PV的问题

表数据

现有user_age表如下:
在这里插入图片描述
user_app表如下:
在这里插入图片描述

需求

求:0-10岁的用户、11-20岁的用户、21-30岁的用户、30岁以上的用户使用app的人数(uv)和次数(pv)。

分析

需求乍一看不难,但是如何实现同时求出uv和pv?有的同学可能最先想到的就是uv = count(distinct uid),pv = count(*)。在MySQL中这样写固然可以得到结果,但是在大数据场景中呢?如果是Hive中这样写发生数据倾斜了怎么处理?所以我们需要换一种思路。

  • 首先可以在user_app表中,按照uid分组,这样就做到了对uid的去重,同时count(*)求出每个用户打开app的次数,记作u_pv。
  • 然后根据user_age表,使用case when计算每个用户所属年龄段,记作age_range。
  • 上面两张表做join,按照age_range分组,count(*)即uv(第一步user_app表已经按照uid去重),sum(u_pv)即为pv。

大数据场景优化版SQL

SELECT
    age_range,
    COUNT(*) uv,
    SUM(u_pv) pv
FROM
(
SELECT 
    uid,
    COUNT(*) u_pv
FROM user_app
GROUP BY uid
) t0
JOIN 
(
SELECT
    uid,
    (
    CASE WHEN age>0 AND age<=10 THEN '0-10岁'
    WHEN age>=11 AND age <=20 THEN '11-20岁'
    WHEN age>=21 AND age <=30 THEN '21-30岁'
    ELSE '31岁以上' END
    ) age_range
FROM
    user_age
) t1
ON t0.uid = t1.uid
GROUP BY age_range;

一般场景SQL

SELECT
    age_range,
    COUNT(DISTINCT uid) uv,
    count(*) pv
from
(
SELECT
 u.uid,age,
 (case when age>0 and age<=10 THEN '0-10岁'
  when age>=11 and age<=20 then '11-20岁'
  when age>=21 and age<=30 then '21-30岁'
  else '31岁以上' end) age_range
FROM
    user_age u
JOIN
    user_app a
ON u.uid = a.uid) t1
group by age_range;
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值