转化率统计
表名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. 求每一步相对于第一步的转化率
-
求出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
-
计算每一步相对第一步的转化率,使用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. 求每一步相对于上一步的转化率
-
使用窗口函数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升序排序。
-
计算每一步相对于上一步的转化率,使用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)
-
自连接,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 ...
-
当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
-
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
-
计算每一步相对于上一步的转化率
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