漏斗转化率统计实战 &(hive严格模式,本地模式)


转化率统计

表名order.txt
字段id, name, pv

1,广告,10000
2,菜单,3000
3,详情,2600
4,购物车,300
5,下单,200
6,支付,190
7,支付ok,189

用到关键技术:
自连接,窗口函数max


前期准备:

create database if not exists hive_order;
use hive_order;
drop table if exists t_order;
create table t_order(id int,name string,pv int) row format delimated fields terminated by “,”;
load data local inpath"/home/hadoopUser/order.txt" into table t_order;
select * from t_order;
desc t_order;


使用严格模式(set hive.mapred.mode = strict;)可以禁止3种类型的查询:
(1)对于分区表,不加分区字段过滤条件,不能执行
(2)对于order by语句,必须使用limit语句。
(3)限制笛卡尔积的查询(join的时候不使用on,而使用where的)

我们要对表进行自连接,所以这里不作严格模式,设置为非严格。
set hive.mapred.mode = nonstrict;(默认undefined)

开启本地模式,对于数据量比较少,执行时间会缩短。
set hive.exec.mode.local.auto=true;(默认为false)

如此一来,对数据量比较小的操作,就可以在本地执行,这样要比提交任务到集群执行效率要快很多。


1. 求每一步相对于第一步的转化率

  1. 求出pv的最大值,把最大值作为一列
    select a.*,b.bpv from t_order a,(select max(pv) bpv from t_order) b;
    或者直接使用max窗口函数:
    select *,max(pv) over(order by id) bpv from t_order;

    id      name	pv		bpv
    1       广告    10000   10000
    2       菜单    3000    10000
    3       详情    2600    10000
    4       购物车  300     10000
    5       下单    200     10000
    6       支付    190     10000
    7       支付ok  189     10000
    
  2. 计算每一步相对第一步的转化率,使用pv/bpv

    select t.*,t.pv/t.bpv from 
    (select a.*,b.bpv from t_order a,(select max(pv) bpv from t_order) b) t;
    或者:
    select t.*,(t.pv/t.bpv) from (select *,max(pv) over(order by id) bpv from t_order) t;
    
    id		name	pv		bpv		pv/bpv	
    1       广告    10000   10000   1.0
    2       菜单    3000    10000   0.3
    3       详情    2600    10000   0.26
    4       购物车  300     10000   0.03
    5       下单    200     10000   0.02
    6       支付    190     10000   0.019
    7       支付ok  189     10000   0.0189
    

2. 求每一步相对于上一步的转化率

  1. 使用窗口函数max,保留本条记录与上一条记录相比的最大值
    select id,name,pv,
    max(pv) over(order by id rows between 1 preceding and current row)
    from t_order;

    id		name	pv		max(pv)
    1       广告    10000   10000
    2       菜单    3000    10000
    3       详情    2600    3000
    4       购物车  300     2600
    5       下单    200     300
    6       支付    190     200
    7       支付ok  189     190
    

    这里不设分区,直接根据id升序排序。

  2. 计算每一步相对于上一步的转化率,使用pv/max(pv)
    select id,name,pv,
    max(pv) over(order by id rows between 1 preceding and current row),
    pv/max(pv) over(order by id rows between 1 preceding and current row)
    from t_order;

    id		name	pv		max(pv)	pv/max(pv)
    1       广告    10000   10000   1.0
    2       菜单    3000    10000   0.3
    3       详情    2600    3000    0.8666666666666667
    4       购物车  300     2600    0.11538461538461539
    5       下单    200     300     0.6666666666666666
    6       支付    190     200     0.95
    7       支付ok  189     190     0.9947368421052631
    

3. 求每一步相对于上一步的转化率(方法2)

  1. 自连接,49条记录
    select a.*,b.id,b.pv from t_order a join t_order b;

    1       广告    10000   1       10000
    2       菜单    3000    1       10000
    3       详情    2600    1       10000
    4       购物车  300     1       10000
    5       下单    200     1       10000
    6       支付    190     1       10000
    7       支付ok  189     1       10000
    1       广告    10000   2       3000
    2       菜单    3000    2       3000
    3       详情    2600    2       3000
    4       购物车  300     2       3000
    5       下单    200     2       3000
    6       支付    190     2       3000
    7       支付ok  189     2       3000
    1       广告    10000   3       2600
    ...
    
  2. 当a.id = b.id +1,那么a.pv的值就等于b.pv的下一个值
    比如:
    当a=1,处于第一步广告阶段,a.pv=10000,但是没有b=0的记录,所以无法匹配。
    当a=2,处于第二步菜单阶段,a.pv=3000,
    b=1+1=2,处于第一步广告阶段,b.pv=10000
    select a.*,b.id,b.pv from t_order a join t_order b on a.id = b.id+1;

    a	                  	b
    2       菜单    3000    1       10000
    3       详情    2600    2       3000
    4       购物车  300     3       2600
    5       下单    200     4       300
    6       支付    190     5       200
    7       支付ok  189     6       190
    
  3. a的值还缺少a=1,所以需要连接,把a=1的记录加到表中
    select a.*,b.id,b.pv from t_order a join t_order b on a.id = b.id+1
    union
    select *,id as bid,pv as bpv from t_order where id =1;

    a                       b
    1       广告    10000   1       10000
    2       菜单    3000    1       10000
    3       详情    2600    2       3000
    4       购物车  300     3       2600
    5       下单    200     4       300
    6       支付    190     5       200
    7       支付ok  189     6       190
    
  4. 计算每一步相对于上一步的转化率
    select t.*,t.apv/t.bpv from
    (select a.id as aid,a.name as aname,a.pv as apv,
    b.id as bid,b.pv as bpv
    from t_order a join t_order b on a.id = b.id+1
    union
    select a.id as aid,a.name as aname,a.pv as apv,
    a.id as bid,a.pv as bpv
    from t_order a where a.id =1) t;

    aid     aname  	apv		bid		bpv		apv/bpv	
    1       广告    10000   1       10000   1.0
    2       菜单    3000    1       10000   0.3
    3       详情    2600    2       3000    0.8666666666666667
    4       购物车  300     3       2600    0.11538461538461539
    5       下单    200     4       300     0.6666666666666666
    6       支付    190     5       200     0.95
    7       支付ok  189     6       190     0.9947368421052631
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章