为了突出重点,总结就写在最前面了。从拿到需求开始,我们经历了以下步骤来完成工作:

  • 需求分析
  • 设计测试数据集及测试用例
  • 数据清洗
  • 需要实现
  • 测试

其中数据清洗主要是做了两个工作:

  1. 去掉用户每一次访问中重复的页面记录,只保留每个页面的最后一次访问记录。
  2. 将用户访问记录进行合并,将所有访问过的页面和访问时间整合到1行当中。

实现的判断依据如下:

  • 乱序漏斗:访问的页面数小于4,或者页面顺序不对。
  • 顺序漏斗:访问的页面数等于4,且页面顺序严格对应。
  • 顺序间隔漏斗:访问的页面数等于4,且页面顺序严格对应,且访问B页面的时间-访问A页面的时间超过2小时。

实现过程中主要使用了下面的函数:

rank
concat_ws
collect_set
split
unix_timestamp
子查询

需求

概述
一般来说,客户会按照A->B->C->D的顺序来访问页面,而且越到后面的页面访问率就越低,比如A是网站首页,B是列表页,C是详情页,D是支付页,根据常识,很容易知道A页面的访问率是最高的而D则是最低的。

现在有一个需求:使用SQL语句来完成以下的工作:

  • 找出乱序访问的用户访问记录,即不按照A->B->C->D的顺序访问的
  • 找出顺序访问的用户访问记录,即严格按照A->B->C->D的顺序访问的
  • 找出顺序的并符合间隔条件的用户访问记录,即严格按照A->B->C->D的顺序访问的,并且访问A后超过2小时再访问B的。

分析

这个需求表述的不是很清楚,我们再来明确一下各种情况应该怎么处理。

首先要完成这种数据漏斗,必须能够将一个用户的每次访问严格的界定开来,即有办法区分每个用户的每次访问都请求了哪些网址,这项工作显然不应该是我们这次的任务,故假定数据集符合该要求。

其次,还有一些特殊的情况的处理需要进一步明确:

  • 如果一个用户在访问下一个页面之前多次访问上一个页面应该如何处理间隔?如A->A->B->C->D
  • 如果一个用户按照顺序访问完后又重新访问某个页面应该如何处理?是算顺序还是逆序?如A->B->C->D->C

对于第1个问题,按照最后一次访问的时间为准;对于第2个问题,则约定其为乱序访问。

数据集及测试用例

我们并没有现成的数据集可以使用。为了说明问题,需要我们自己创建一个数据集用于测试。

表结构设计

为了说明问题方便,在不影响结论的情况下,应该让表结构尽可能的简单。必须的字段包括:

  • session_id 用于界定每个用户的一次访问,在一次访问中的多个请求该字段相同
  • url 请求链接地址
  • req_time 访问页面的时间
  • 测试数据

用等价类划分法来给一些测试数据。等价类大概划成下面这样:

基于这样的等价类划分,可以给出下面的测试数据集:

页面无缺失,顺序,超过间隔,无重复页面
session_id  req_url     req_time
s_01        a.html      2017-03-26 08:00:00
s_01        b.html      2017-03-26 10:01:00
s_01        c.html      2017-03-26 10:03:00
s_01        d.html      2017-03-26 10:04:00页面无缺失,顺序,超过间隔,有重复页面
session_id  req_url     req_time
s_02        a.html      2017-03-26 08:00:00
s_02        a.html      2017-03-26 09:00:00
s_02        b.html      2017-03-26 11:01:00
s_02        c.html      2017-03-26 11:03:00
s_02        d.html      2017-03-26 11:04:00页面无缺失,顺序,间隔不足,无重复页面
session_id  req_url     req_time
s_03        a.html      2017-03-26 08:00:00
s_03        b.html      2017-03-26 09:01:00
s_03        c.html      2017-03-26 09:03:00
s_03        d.html      2017-03-26 09:04:00页面无缺失,顺序,间隔不足,有重复页面
session_id  req_url     req_time
s_04        a.html      2017-03-26 08:00:00
s_04        a.html      2017-03-26 09:00:00
s_04        b.html      2017-03-26 10:01:00
s_04        c.html      2017-03-26 10:03:00
s_04        d.html      2017-03-26 10:04:00页面无缺失,顺序访问完后乱序,超过间隔,有重复页面
session_id  req_url     req_time
s_05        a.html      2017-03-26 08:00:00
s_05        b.html      2017-03-26 10:01:00
s_05        c.html      2017-03-26 10:03:00
s_05        d.html      2017-03-26 10:04:00
s_05        c.html      2017-03-26 11:04:00页面无缺失,顺序访问完后乱序,间隔不足,有重复页面
session_id  req_url     req_time
s_06        a.html      2017-03-26 09:00:00
s_06        b.html      2017-03-26 10:01:00
s_06        c.html      2017-03-26 10:03:00
s_06        d.html      2017-03-26 10:04:00
s_06        c.html      2017-03-26 11:04:00页面无缺失,其他乱序,超过间隔,有重复页面
session_id  req_url     req_time
s_07        a.html      2017-03-26 07:00:00
s_07        b.html      2017-03-26 10:01:00
s_07        c.html      2017-03-26 10:03:00
s_07        d.html      2017-03-26 10:04:00
s_07        c.html      2017-03-26 11:04:00页面无缺失,其他乱序,超过间隔,无重复页面
session_id  req_url     req_time
s_08        a.html      2017-03-26 07:00:00
s_08        c.html      2017-03-26 10:01:00
s_08        b.html      2017-03-26 10:03:00
s_08        d.html      2017-03-26 10:04:00页面无缺失,其他乱序,间隔不足,有重复页面
session_id  req_url     req_time
s_09        a.html      2017-03-26 09:00:00
s_09        b.html      2017-03-26 10:01:00
s_09        c.html      2017-03-26 10:03:00
s_09        d.html      2017-03-26 10:04:00
s_09        c.html      2017-03-26 11:04:00页面无缺失,其他乱序,间隔不足,无重复页面
session_id  req_url     req_time
s_10        a.html      2017-03-26 09:00:00
s_10        c.html      2017-03-26 10:01:00
s_10        b.html      2017-03-26 10:03:00
s_10        d.html      2017-03-26 10:04:00页面缺失,其他乱序,超过间隔,有重复页面
session_id  req_url     req_time
s_11        a.html      2017-03-26 07:00:00
s_11        b.html      2017-03-26 10:03:00
s_11        d.html      2017-03-26 10:04:00
s_11        d.html      2017-03-26 11:04:00页面缺失,其他乱序,超过间隔,无重复页面
session_id  req_url     req_time
s_12        a.html      2017-03-26 07:00:00
s_12        b.html      2017-03-26 10:03:00
s_12        d.html      2017-03-26 10:04:00页面缺失,其他乱序,间隔不足,有重复页面
session_id  req_url     req_time
s_13        a.html      2017-03-26 07:00:00
s_13        d.html      2017-03-26 10:04:00
s_13        d.html      2017-03-26 11:04:00页面缺失,其他乱序,间隔不足,无重复页面
session_id  req_url     req_time
s_14        a.html      2017-03-26 07:00:00
s_14        d.html      2017-03-26 10:04:00

测试用例

有了数据集,我们就可以给出下面的测试

数据漏斗 期望输出 实际输出

乱序漏斗

s_05
s_06
s_07
s_08
s_09
s_10
s_11
s_12
s_13
s_14
 
顺序漏斗

s_01
                            s_02
                            s_03
                            s_04

 
顺序间隔漏斗 s_01
s_02
 

准备工作

完成了需求分析以及测试数据和测试用例的准备以后,我们就可以开始实现这几个数据漏斗了。

使用下面的命令在Hive中创建一个表,用于存放用户访问数据。

use test_db;create table t_visitlog(session_id string,req_url string,req_time timestamp)
row format delimited
fields terminated by ',';

然后创建一个数据文件,visitlog.data,输入下面的内容:

s_01,a.html,2017-03-26 08:00:00
s_01,b.html,2017-03-26 10:01:00
s_01,c.html,2017-03-26 10:03:00
s_01,d.html,2017-03-26 10:04:00
s_02,a.html,2017-03-26 08:00:00
s_02,a.html,2017-03-26 09:00:00
s_02,b.html,2017-03-26 11:01:00
s_02,c.html,2017-03-26 11:03:00
s_02,d.html,2017-03-26 11:04:00
s_03,a.html,2017-03-26 08:00:00
s_03,b.html,2017-03-26 09:01:00
s_03,c.html,2017-03-26 09:03:00
s_03,d.html,2017-03-26 09:04:00
s_04,a.html,2017-03-26 08:00:00
s_04,a.html,2017-03-26 09:00:00
s_04,b.html,2017-03-26 10:01:00
s_04,c.html,2017-03-26 10:03:00
s_04,d.html,2017-03-26 10:04:00
s_05,a.html,2017-03-26 08:00:00
s_05,b.html,2017-03-26 10:01:00
s_05,c.html,2017-03-26 10:03:00
s_05,d.html,2017-03-26 10:04:00
s_05,c.html,2017-03-26 11:04:00
s_06,a.html,2017-03-26 09:00:00
s_06,b.html,2017-03-26 10:01:00
s_06,c.html,2017-03-26 10:03:00
s_06,d.html,2017-03-26 10:04:00
s_06,c.html,2017-03-26 11:04:00
s_07,a.html,2017-03-26 07:00:00
s_07,b.html,2017-03-26 10:01:00
s_07,c.html,2017-03-26 10:03:00
s_07,d.html,2017-03-26 10:04:00
s_07,c.html,2017-03-26 11:04:00
s_08,a.html,2017-03-26 07:00:00
s_08,c.html,2017-03-26 10:01:00
s_08,b.html,2017-03-26 10:03:00
s_08,d.html,2017-03-26 10:04:00
s_09,a.html,2017-03-26 09:00:00
s_09,b.html,2017-03-26 10:01:00
s_09,c.html,2017-03-26 10:03:00
s_09,d.html,2017-03-26 10:04:00
s_09,c.html,2017-03-26 11:04:00
s_10,a.html,2017-03-26 09:00:00
s_10,c.html,2017-03-26 10:01:00
s_10,b.html,2017-03-26 10:03:00
s_10,d.html,2017-03-26 10:04:00
s_11,a.html,2017-03-26 07:00:00
s_11,b.html,2017-03-26 10:03:00
s_11,d.html,2017-03-26 10:04:00
s_11,d.html,2017-03-26 11:04:00
s_12,a.html,2017-03-26 07:00:00
s_12,b.html,2017-03-26 10:03:00
s_12,d.html,2017-03-26 10:04:00
s_13,a.html,2017-03-26 07:00:00
s_13,d.html,2017-03-26 10:04:00
s_13,d.html,2017-03-26 11:04:00
s_14,a.html,2017-03-26 07:00:00
s_14,d.html,2017-03-26 10:04:00

然后使用下面的命令将其上传到hdfs中。

hadoop fs -put visitlog.data /user/hive/warehouse/test_db.db/t_visitlog/

然后使用下面的SQL语句检查是否上传成功:

select * from t_visitlog;

我这边是上传成功的。到这里我们就完成了准备工作。

数据清洗

接下来,我们要将数据进行一些处理,使得后面的工作更容易开展,主要工作包括:

  1. 去掉每一次访问中重复的页面记录,只保留每个页面的最后一次访问记录。
  2. 将用户访问记录进行合并,每个session_id对应一行记录。

去掉重复的页面记录

使用下面的SQL语句即可实现去掉每一次访问中重复的页面记录,同时只保留每个页面最后一次访问记录。

DEMON1:select session_id,req_url,req_time from(select session_id,req_url,req_time,rank() over(partition by session_id,req_url order by req_time desc) as rank from(select session_id,req_url,req_timefrom t_visitlogdistribute by session_id,req_urlsort by session_id,req_time desc)a
)b
where rank = 1;--------------------------------------------------------------------------------DEMON2:select session_id,req_url,max(req_time)
from t_visitlog
group by session_id,req_url

为了粘贴方便,这里就不缩进了。

为了方便后续的操作,我们使用下面的SQL语句将查询结果放到一个新的表t_vlog_norepeat中。

使用下面的命令来查看一下新创建的表的结构:

desc t_vlog_norepeat;

输出结果如下:

session_id              string
req_url                 string
req_time                timestamp

是符合我们要求的。

合并访问记录

使用下面的命令将访问记录保存到t_vlog_merge表中去。

create table t_vlog_merge as
select session_id,concat_ws(',',collect_set(vr)) as vtext
from(select distinct session_id,concat_ws('_',cast(req_time as string),req_url) as vr from (select session_id,req_url,req_time from t_vlog_norepeat sort by session_id,req_time asc)a
) temp
group by session_id;

结果如下:

s_01    2017-03-26 08:00:00_a.html,2017-03-26 10:01:00_b.html,2017-03-26 10:03:00_c.html,2017-03-26 10:04:00_d.html
s_02    2017-03-26 09:00:00_a.html,2017-03-26 11:01:00_b.html,2017-03-26 11:03:00_c.html,2017-03-26 11:04:00_d.html
s_03    2017-03-26 08:00:00_a.html,2017-03-26 09:01:00_b.html,2017-03-26 09:03:00_c.html,2017-03-26 09:04:00_d.html
s_04    2017-03-26 09:00:00_a.html,2017-03-26 10:01:00_b.html,2017-03-26 10:03:00_c.html,2017-03-26 10:04:00_d.html
s_05    2017-03-26 08:00:00_a.html,2017-03-26 10:01:00_b.html,2017-03-26 10:04:00_d.html,2017-03-26 11:04:00_c.html
s_06    2017-03-26 09:00:00_a.html,2017-03-26 10:01:00_b.html,2017-03-26 10:04:00_d.html,2017-03-26 11:04:00_c.html
s_07    2017-03-26 07:00:00_a.html,2017-03-26 10:01:00_b.html,2017-03-26 10:04:00_d.html,2017-03-26 11:04:00_c.html
s_08    2017-03-26 07:00:00_a.html,2017-03-26 10:01:00_c.html,2017-03-26 10:03:00_b.html,2017-03-26 10:04:00_d.html
s_09    2017-03-26 09:00:00_a.html,2017-03-26 10:01:00_b.html,2017-03-26 10:04:00_d.html,2017-03-26 11:04:00_c.html
s_10    2017-03-26 09:00:00_a.html,2017-03-26 10:01:00_c.html,2017-03-26 10:03:00_b.html,2017-03-26 10:04:00_d.html
s_11    2017-03-26 07:00:00_a.html,2017-03-26 10:03:00_b.html,2017-03-26 11:04:00_d.html
s_12    2017-03-26 07:00:00_a.html,2017-03-26 10:03:00_b.html,2017-03-26 10:04:00_d.html
s_13    2017-03-26 07:00:00_a.html,2017-03-26 11:04:00_d.html
s_14    2017-03-26 07:00:00_a.html,2017-03-26 10:04:00_d.html

实现

实现乱序漏斗

我们来分析一下乱序漏斗的几个特征,第1个是按照”,”分割后长度不为4,第2个就是按照”,”分割后页面顺序不对。

使用下面的代码即可实现乱序漏斗:

select session_id
from(select session_id,vtext,split(vtext,',') as arr from t_vlog_merge
) temp
where size(arr) != 4 or split(arr[0],'_')[1] != 'a.html'
or split(arr[1],'_')[1] != 'b.html' or split(arr[2],'_')[1] != 'c.html'
or split(arr[3],'_')[1] != 'd.html';

结果:

s_05
s_06
s_07
s_08
s_09
s_10
s_11
s_12
s_13
s_14

实现顺序漏斗

使用下面的代码即可实现顺序漏斗:

select session_id
from(select session_id,vtext,split(vtext,',') as arr from t_vlog_merge
) temp
where size(arr) == 4 and split(arr[0],'_')[1] == 'a.html'
and split(arr[1],'_')[1] == 'b.html' and split(arr[2],'_')[1] == 'c.html'
and split(arr[3],'_')[1] == 'd.html';

结果:

s_01
s_02
s_03
s_04

实现顺序间隔漏斗

使用下面的代码可以实现顺序间隔漏斗(访问A页面2小时以后访问B):

select session_id
from(select session_id,vtext,split(vtext,',') as arr from t_vlog_merge
) temp
where size(arr) == 4 and split(arr[0],'_')[1] == 'a.html'
and split(arr[1],'_')[1] == 'b.html' and split(arr[2],'_')[1] == 'c.html'
and split(arr[3],'_')[1] == 'd.html'
and unix_timestamp(split(arr[1],'_')[0]) - unix_timestamp(split(arr[0],'_')[0]) > 7200;

结果:

s_01
s_02

测试

上面已经测试过了,测试结果如下:

数据漏斗 期望输出 实际输出
乱序漏斗 s_05
s_06
s_07
s_08
s_09
s_10
s_11
s_12
s_13
s_14
s_05
s_06
s_07
s_08
s_09
s_10
s_11
s_12
s_13
s_14
顺序漏斗 s_01
s_02
s_03
s_04
s_01
s_02
s_03
s_04
顺序间隔漏斗 s_01
s_02
s_01
s_02

Hive基于SQL创建漏斗模型相关推荐

  1. Amazon Redshift ML现已正式推出——使用SQL创建机器学习模型并通过您的数据进行预测

    借助 Amazon Redshift,您可以使用SQL在您的数据仓库.操作数据库和数据湖中查询和合并数EB的结构化和半结构化数据.现在,AQUA(高级查询加速器)已全面推出,您可以将您的查询性能最高提 ...

  2. 1w字详解 ClickHouse漏斗模型实践方案(收藏)

    作者:互联网大数据团队- Wu Yonggang 日常工作中做为数仓开发工程师.数据分析师经常碰到漏斗分析模型,本文详细介绍漏斗模型的概念及基本原理,并阐述了其在平台内部的具体实现.针对实际使用过程的 ...

  3. hive hsql 漏斗模型_数据分析之SQL:常用模型

    以下介绍常用的SQL写法: case when的用法---不管偏不偏,你可能真没见过这种写法 内连接VS左连接---80%的业务代码都与之相关 distinct的用法--你可能真的错怪distinct ...

  4. Hive在SQL标准权限模式下创建UDF失败的问题排查

    环境: CDH 5.16 Hive 1.1.0 已开启Kerberos Hive 授权使用SQL StandardsBased Authorization模式(以下简称SSBA模式) 症状表现: 在编 ...

  5. MS CRM 2011 如何创建基于SQL的自定义报表,并使用数据预筛选(Pre-Filtering)

    原创地址:http://www.cnblogs.com/jfzhu/archive/2012/10/03/2711123.html 转载请注明出处 在本文中我将介绍如何使用Business Intel ...

  6. 什么是营销漏斗模型?如何创建一个营销漏斗策略

    营销漏斗对于了解用户所处生命旅程的位置,非常重要.所以了解它的工作原理以及如何创建一个营销漏斗来提高转化率是营销人员的核心工作.本文将带您了解什么是营销漏斗.营销漏斗背后的流程和理论,以及如何使用示例 ...

  7. MSCRM中报表开发一:创建基于SQL报表

    1.       新建报表项目.打开SQL Server Business Intelligence Development Studio,点击 文件 > 新建 > 项目,项目类型选择 商 ...

  8. hive SQL 创建数据库,创建hive表、查询时,其表名,字段,统统不区分大写(在底层一律转换为小写)

    hive SQL 创建数据库,创建hive表.查询时,其表名,字段,统统不区分大写(在底层一律转换为小写) (1).默认default数据库 hive默认自带一个名为default的数据库,如果建表时 ...

  9. 【EPS精品教程】基于DOM和DSM创建垂直模型、加载垂直模型

    本教程讲解EPS三维测图模块,主要内容有新建工程.创建垂直模型,为后续工作做准备. 目录 一.创建工程 二.生成垂直摄影模型

最新文章

  1. 什么是 Design System
  2. cxf实现webservice
  3. htmlparser解决PKIX path building failed问题的两种方法
  4. FlexoCalendar周日历出错的解决方法
  5. HDU 2567 寻梦(字符串,插入)
  6. 【小白学PyTorch】1.搭建一个超简单的网络
  7. 使用LOAD DATA和INSERT语句导入Mysql数据
  8. make: *** [.build_release/lib/libcaffe.so] 错误 1
  9. jquery 使用下拉效果的实现
  10. dbml mysql_深度好文:全方位了解MLDB数据库
  11. 应届生毕业第一份工资多少?
  12. 腾讯云技术布道师贺嘉正式受邀出席SDCC 2016微信开发专题,分享腾讯云的小程序解决方案...
  13. 信息学奥赛一本通 铲雪车
  14. 性能优化: 资源合并与压缩 -- 压缩(前端开发过程中 JavaScript、HTML、CSS 文件的压缩)
  15. ios duang 动画简记
  16. 网线直接接电脑可以上网,但是接到无线路由器上,就不能上网了
  17. 创基MIFI转换器轻松上网不是难事
  18. 人工智能对话系统在VUI和GUI结合下对于控件调用的调研报告
  19. 关于JDK8和JDK11切换问题
  20. 【杂记】万用表测试三极管

热门文章

  1. UL-1973-2022 储能电池安全标准
  2. ssi 指令 php,SSI 漏洞学习笔记
  3. Unity 2D横版移动跳跃
  4. 小白零基础教学:用自助BI工具搭建领导驾驶舱
  5. 人手,人力,人才,人物
  6. 数学之路(3)-数据分析(4)
  7. OpenJudge Tian Ji -- The Horse Racing
  8. 2018年全国多校算法寒假训练营练习比赛(第五场)F-The Biggest Water Problem
  9. JAVA练习题:求税后工资问题
  10. 自定义redisTemplate以及redisutils的封装使用