Hive-SQL面试题1

0. 需求

 我们有如下的用户访问数据
    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

 1.实现

      窗口函数典型案例

      (1) 数据准备

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 

    (2)创建hive表

CREATE TABLE dan_test.sqltest1 ( 
        userId string, 
        visitDate string,
        visitCount string )
ROW format delimited FIELDS TERMINATED BY "\t";

load data local inpath "/home/centos/dan_test/sqltest1.txt" into table sqltest1;

   (3)需求实现

     ① 将时间进行格式化,转换成题目要求的时间

    采用date_format函数+regexp_replace函数

select date_format(regexp_replace(visitdate,'/','-'),'yyyy-MM') from sqltest1

hive> select date_format(regexp_replace(visitdate,'/','-'),'yyyy-MM') from sqltest1;
OK
2017-01
2017-01
2017-01
2017-01
2017-01
2017-02
2017-01
2017-02
Time taken: 0.15 seconds, Fetched: 8 row(s)

    转换日期作为子表

SELECT userid
      ,date_format(regexp_replace(visitdate,'/','-'),'yyyy-MM') AS visitmonth
      ,visitcount
FROM sqltest1

  ② 分析函数+窗口函数实现

    注意求用户每月汇总额的时候注意去重,如不去重则是如下结果。为什么需要去重?因为窗口函数作用的是每条记录,在每条记录的后面都会形成结果,其分析函数,分析的范围是over()函数中所指定的,这一点一定要弄明白

select t.userid as userid  
      ,t.visitmonth as visitmonth
      ,sum(t.visitcount) over(partition BY userid,visitmonth) as sum_per_month
  from
   (
     SELECT userid
      ,date_format(regexp_replace(visitdate,'/','-'),'yyyy-MM') AS visitmonth
      ,visitcount
    FROM sqltest1
  )t

     本题最终的结果如下:

select s.userid
      ,s.visitmonth
      ,s.sum_per_month
      ,sum(s.sum_per_month) over(partition BY s.userid order by s.visitmonth) as total_visitcount
from
(
   select distinct t.userid as userid  
          ,t.visitmonth as visitmonth
         ,sum(t.visitcount) over(partition BY userid,visitmonth) as sum_per_month
  from
   (
     SELECT userid
      ,date_format(regexp_replace(visitdate,'/','-'),'yyyy-MM') AS visitmonth
      ,visitcount
    FROM sqltest1
  )t
)s

2 小 结

   本题主要的使用知识点归纳如下:

  •   (1)regexp_replace函数的使用
  •   (2)date_format函数的使用
  •   (3)窗口函数与分析函数的结合使用。当然本题也可以不用窗口函数分析,也可以使用group by完成,读者自行尝试

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章