最近遇到一个关于sql的维度统计问题,要求统计各时间段内不同类型的浏览器的活跃人数,并计算各时间段内活跃用户总数。听起来十分简单,但是深究下来发现,同一个用户某时间段内会点击多次,而且可能是使用了不同的浏览器来进行点击,所以这里就涉及到一个浏览器维度内的去重和一个时间段维度内的去重。如下:

仔细思考,对表中数据进行如上统计时,浏览器维度统计要求同一个用户内部去重(同一个浏览器),而时间维度的总数统计要求对同一个用户去重(分属于不同浏览器),但是最终的结果都要再按照时间维度进行最终统计。
所以将浏览器维度的统计与活跃总数的统计拆为两条sql查询,最终通过对日期字段的关联查询实现上述结果。
我们假设表中有下列数据:

1. 浏览器维度统计
select
times,
sum(if(browser_type='Google',count,0)) as Google,
sum(if(browser_type='IE',count,0)) as IE,
sum(if(browser_type='Other',count,0)) as Other
from
(select
count(distinct user_id) as count,
browser_type,
date_format(times,'%Y-%m-%d %H') as times
from
t_log
group by
browser_type,
date_format(times,'%Y-%m-%d %H')
) t
group by
times
从内层向外分析,我们先根据times,browser_type分组,统计各浏览器每个小时的活跃度,同时对user_id去重计数;然后,行转列,输出业务要求的表格结果。
执行结果如下:

2.时间维度统计总数
select
date_format(times,'%Y-%m-%d %H') as times,
count( distinct user_id) as total
from
t_log
group by
date_format(times,'%Y-%m-%d %H')
执行结果如下:

3.按时间维度统计所有
select
*
from
(
select
times,
sum(if(browser_type='Google',count,0)) as Google,
sum(if(browser_type='IE',count,0)) as IE,
sum(if(browser_type='Other',count,0)) as Other
from
(select
count(distinct user_id) as count,
browser_type,
date_format(times,'%Y-%m-%d %H') as times
from
t_log
group by
browser_type,
date_format(times,'%Y-%m-%d %H')
) t
group by
times) browser
left join (
select
date_format(times,'%Y-%m-%d %H') as times,
count( distinct user_id) as total
from
t_log
group by
date_format(times,'%Y-%m-%d %H')
) total
using(times)
最终输出结果:

本文探讨了一个SQL统计问题,涉及在不同时间区间内按浏览器类型统计活跃用户数量,同时处理同一用户在不同浏览器间的重复。通过两条SQL查询分别处理浏览器维度的去重和时间维度的去重,最后结合日期字段得到最终统计结果。
948

被折叠的 条评论
为什么被折叠?



