HIVE连续登录问题以及行列转换问题

连续登录问题:

实现思路:

1.因为每天用户登录次数可能不止一次,所以需要先将用户每天的登录日期去重。

2.再用row_number() over(partition by _ order by _)函数将用户id分组,按照登陆时间进行排序。

3.计算登录日期减去第二步骤得到的结果值,用户连续登陆情况下,每次相减的结果都相同。这里使用到的是date_sub函数

在这里我讲一下date_sub与date_diff函数的区别:

(1). datediff('endTime',‘startTime’)是两个日期相减

(2).date_sub(‘yyyy-MM-dd’,n/-m)  为一个日期减去一个数字

4.按照id和日期分组并求和,筛选大于等于7的即为连续7天登陆的用户

4.1下面给出sql :求出每个用户最大的登录时间

 1 SELECT user_id, MAX(count_val) AS max_count  -- 查出了最大连续登陆,where>=7,即7天连续
 2 FROM (
 3      -- group by相同日期
 4   SELECT user_id, symbol_date, COUNT(*) AS count_val
 5   FROM (
 6        -- 日期减rank,连续登陆的话,会得到相同日期
 7     SELECT user_id, log_date, date_sub(log_date, CAST(rn AS INT)) AS symbol_date
 8     FROM (
 9       SELECT user_id, log_date, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY log_date) AS rn  --  rank函数分区 排序
10      FROM (
11       select distinct user_id,log_date from user_logging_format
12       ) a --去重
13     ) c
14   ) d
15   GROUP BY user_id, symbol_date
16 ) e
17 GROUP BY user_id;

 

  4.2判断登录连续登录7天的用户

 1 SELECT user_id -- 查出连续登陆,where>=7,即7天连续的用户
 2 FROM (
 3      -- group by相同日期
 4   SELECT user_id, symbol_date, COUNT(*) AS count_val
 5   FROM (
 6        -- 日期减rank,连续登陆的话,会得到相同日期
 7     SELECT user_id, log_date, date_sub(log_date, CAST(rn AS INT)) AS symbol_date
 8     FROM (
 9       SELECT user_id, log_date, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY log_date) AS rn  --  rank函数分区 排序
10      FROM (
11       select distinct user_id,log_date from user_logging_format
12       ) a --去重
13     ) c
14   ) d
15   GROUP BY user_id, symbol_date
16 ) e
17 where count_val>=7;

 

  2.行列转换问题:

首先你必须知道几个函数:

collect_set();collect_list():它们都是将分组中的某列转为一个数组返回,不同的是collect_list不去重而collect_set去重。

CONCAT_WS(separator,str1,str2,…):第一个参数为分隔符:

下面从网上找的几个图片:

 

下面使用完collect_set,一目了然:

select
username, collect_set(video_name)
from t_visit_video
group by username;

  

上边是多行转一行,那么一行转多行如何转?

a       b       1,2,3
c       d       4,5,6
1 select col1, col2, col5
2 from tmp_bsf_test a
3 lateral  view explode(split(col3,','))  b AS col5

 

  这里是笛卡尔乘积:相当于col1,col2他们两个乘以col5因为col5里面有explode

a       b       1
a       b       2
a       b       3
c       d       4
c       d       5
c       d       6

  下面有个例子看看你会不会,也是从网上找的

 

1 SELECT SID,
2 MAX(case CID when '01' then score else 0 end) '01', --as 语文
3 MAX(case CID when '02' then score else 0 end)'02',   --as 数学
4 MAX(case CID when '03' then score else 0 end)'03'
5 FROM SC
6 GROUP BY SID

 

 上面是人家写的代码:这里首先是按id分组,没毛病,这里需要使用到聚合函数,为了是取别名  as 语文像这样,思路就是这个思路

posted @ 2021-11-07 20:41  小阿政  阅读(432)  评论(0编辑  收藏  举报