第1题
有如下的用户访问数据
userId | visitDate | visitCount |
---|---|---|
u01 | 2017/1/21 | 5 |
u02 | 2017/1/23 | 6 |
u03 | 2017/1/22 | 8 |
u04 | 2017/1/20 | 3 |
u01 | 2017/1/23 | 6 |
u01 | 2017/2/21 | 8 |
u02 | 2017/1/23 | 6 |
u01 | 2017/2/22 | 4 |
要求使用SQL统计出每个用户的累积访问次数,如下表所示:
用户id | 月份 | 小计 | 累积 |
---|---|---|---|
u01 | 2017-01 | 11 | 11 |
u01 | 2017-02 | 12 | 23 |
u02 | 2017-01 | 12 | 12 |
u03 | 2017-01 | 8 | 8 |
u04 | 2017-01 | 3 | 3 |
数据:
u01 2017/1/21 5
u02 2017/1/23 6
u03 2017/1/22 8
u04 2017/1/20 3
u01 2017/1/23 6
u01 2017/2/21 8
u02 2017/1/23 6
u01 2017/2/22 4
*参考答案:*
sql
create table jd(
id string,
data string,
count int
)row format delimited fields terminated by ' ';
load data local inpath '/opt/hive_data/jd' into table jd;
-- over后写字段名 子查询不用表名.字段名。 单表自连接才必须用表名.字段名
select id `用户id`,vDate `月份` ,`小计`,sum(`小计`)
over(partition by id order by vDate rows between unbounded preceding and current row ) `累积`
from
(select id,vDate,sum(count) `小计` from
(select id ,date_format(regexp_replace(data,'/','-'),'yyyy-MM') as vDate ,count from jd) t1
group by id,vDate) t2
--date是string类型,若用此函数,必须满足date的标准格式.
select year(date) from jd;
-- 执行成功
select date_format('2023-1-9','yyyy-MM') datee;
-- 第一个参数必须满足hive的时间格式,第二个自定义
select date_format('2023-01-01 12:30:5','yyyy/MM/dd - HH/mm/ss') datee;
-- 这里执行失败。 '2023-1' 并不是可以识别的日期格式
select date_format('2023-1','yyyy-MM') datee;
第2题
有50W个京东店铺,每个顾客访客访问任何一个店铺的任何一个商品时都会产生一条访问日志,访问日志存储的表名为Visit,访客的用户id为user_id,被访问的店铺名称为shop,请统计:
1)每个店铺的UV(访客数)
Select shop, count(user_id) from visit group by shop;
2)每个店铺访问次数top3的访客信息。输出店铺名称、访客id、访问次数
数据:
u1 a
u2 b
u1 b
u1 a
u3 c
u4 b
u1 a
u2 c
u5 b
u4 b
u6 c
u2 c
u1 b
u2 a
u2 a
u3 a
u5 a
u5 a
u5 a
*参考答案*
sql
create table jd2(
username string,
shopname string
)row format delimited fields terminated by ' ';
load data local inpath '/opt/hive_data/jd2' into table jd2;
select * from jd2 tablesample ( 3 rows )
-- 第一步:统计每一个店铺每一位顾客的访问次数
select shop, userid, count(*) as visit_count from visit group by shop, userid;
-- 第二步:对统计出来的访问次数排序(每一个店铺中分别排序)并给定编号
select *,
rank() over(partition by shop order by visit_count desc) as n
from (
select shop, userid, count(*) as visit_count from visit group by shop, userid
)t1;
-- 第三步:筛选编号<=3的用户信息
select *
from (
select *,
rank() over(partition by shop order by visit_count desc) as n
from (
select shop, userid, count(*) as visit_count from visit group by shop, userid
)t1
-- 这里的 where 字段是窗口函数的字段。只能在窗口函数的外部中去where
) t2 where n <= 3;