Hive简易教程 - 数据分析

Hive是一个HDFS上的sql执行引擎,它将sql语句转化为Hadoop上的map-reduce任务来执行。由于是写sql,所以使用Hive进行数据分析的好处是没有什么额外的学习成本,但是它是批量式处理的,可能会比较慢。本文将通过几个案例来简单介绍如何使用Hive。

样例数据

** 随机生成一批订单数据(order_id, price, tag, order_date) **

from random import randint
from datetime import date
from datetime import timedelta

for i in range(1000):
    order_id = 'order_%s' % i
    seller_id = 'seller_%s' % randint(0, 300)
    price = randint(0, 100000) / 100.0
    tag = randint(0, 1)
    order_date = date.today() - timedelta(days=randint(0, 30))
    print order_id, seller_id, price, tag, order_date

** 存储数据到Hive **

hive> create table test_order_sample
(order_id string, seller_id string, price double, tag int, order_date string) 
row format delimited fields terminated by ' ';

hive> load data 
local inpath '/data/order_sample' 
into table test_order_sample;

案例一

** 统计出近一周每天成功支付的订单总数,gmv,客单价 **

hive> select order_date,count(*),round(sum(price),2),round(avg(price),2) 
from test_order_sample 
where tag=1 
and order_date>=date_sub(from_unixtime(unix_timestamp(),'yyyy-MM-dd'),7) 
group by order_date 
order by order_date desc;

案例二

** 统计出近一周每天成功支付 及支付失败 各自的订单总数,gmv,客单价 **

select order_date,
sum(if(tag=0,1,0)),sum(if(tag=0,price,0)),avg(if(tag=0,price,0)),
sum(if(tag=1,1,0)),sum(if(tag=1,price,0)),avg(if(tag=1,price,0)) 
from test_order_sample 
where tag=1 
and order_date>=date_sub(from_unixtime(unix_timestamp(),'yyyy-MM-dd'),7) 
group by order_date 
order by order_date desc;

count函数和if条件组合,而不是两个sql join

案例三

** 挑选出近一周gmv>1000并且订单量>2单的卖家ID及其订单 **

hive> select seller_id,collect_set(order_id) 
from test_order_sample 
where tag=1 
and order_date>=date_sub(from_unixtime(unix_timestamp(),'yyyy-MM-dd'),7) 
group by seller_id 
having count(*)>2 
and sum(price)>1000;

常用UDF

聚合相关函数

collect_set(c_1)

  在使用group by之后只能select出group key以及相关的统计数字,但也可以以集合的形式select出任何其他的非group key,比如按卖家ID聚合之后又想查看在这个卖家下单的买家ID:sellect collect_set(buyer_id) from t group by seller_id。

collect_list(c_1)

  与collect_set类似,元素可重复

explode(c_1)

  explode函数可以把一个array类型的数据扁平化。比如,现在每行是一个seller_id集合,使用explode可以扁平化为每行一个seller_id。但explode不可以直接与group by一起使用,比如我想按某些条件筛选一些卖家然后在查看该店铺的买家的情况:select explode(b.buyer_ids) from (select collect_set(buyer_id) as buyer_ids from t group by seller_id) b;

时间函数

unix_timestamp()

  当前时间

from_unixtime(timestamp, format)

  将系统时间戳转化为人可读的数据格式 如:select from_unixtime(unix_timestamp(), ‘yyyy-MM-dd’);

date_sub(string startdate, int days)

  求几天前的日期

其它

nvl(v1, v2)

  nvl函数用于处理null值,当一个字段是null时,这个字段和其它字段进行算术运算时的结果依然为null。这时可以使用这个函数为值可能为null的字段赋予一个默认值,即v2.

instr(str1, ‘xxx’)

  判断字符串’xxx’是否出现在str1中,如果str1是null或者不存在xxx返回值都是0

size(a1)

  返回数组a1的大小

union_all()

  合并两个查询结果,但结果的列数需要一致!!!

    原文作者:八刀一闪
    原文地址: https://www.jianshu.com/p/3fad75c0d50a
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞