HIve 题型总结

易忘命令

格式转换

一般来说 ,都可以使用 cast(字段名 as 格式) 进行强制转换

字符串转日期格式 :

日期格式转字符串:

date_format(日期字段,格式)

yyyy-MM-dd 以年-月-日形式显示日期
HH:mm:ss 以小时:分钟:秒形式显示时间
yyyy-MM-dd HH:mm:ss 同时显示日期和时间
 select date_format("2023-06-03",'yyyy-MM-dd') //2023-06-03
 ​
 SELECT date_format('2022-02-23 14:25:32', 'yyyy-MM-dd HH:mm:ss'); //2022-02-23 14:25:32
 ​
 SELECT date_format('2022-02-23 14:25:32', 'yyyy-MM-dd '); //2022-02-23 

窗口函数

排序

  • rank() over() :

 大小   排名
 1       1
 1       1
 1       1
 3       4     排名序号会出现同名,不连续
  • DENSE_RANK() over() :

 大小   排名
 1       1
 1       1
 1       1
 3       2     排名序号会出现同名,连续
  • ROW_NUMBER() over()

 大小   排名
 1       1
 1       2
 1       3
 3       4     排名序号唯一

向上向下取值

LAG(字段名,n,DEFAULT) 用于统计窗口内往上第n行值

  • n:默认值为1 可省略

  • default 是一个可选参数,表示如果没有找到前一行,不指定的话,返回的默认 null。

LEAD((字段名,n,DEFAULT) 与函数用法同理

题型

累计数据统计

需要每一行统计的是上面行的和 而不是全部的和

方法一:

sum(字段名) over( .......order by 字段名) 常规操作

方法二:滑动求和

 select  *,sum(order_amount ) over(partition by user_id rows between  unbounded preceding and current row )
 from order_info
 1   1001    小元  2022-01-01  10  10
 5   1001    小元  2022-01-05  46  56
 8   1001    小元  2022-01-08  50  106
 3   1001    小元  2022-02-03  23  129
 6   1001    小元  2022-04-06  42  171
 2   1002    小海  2022-01-02  15  15
 4   1002    小海  2022-01-04  29  44
 7   1002    小海  2022-01-07  50  94
 9   1003    小辉  2022-04-08  62  62
 10  1003    小辉  2022-04-09  62  124
 12  1003    小辉  2022-04-11  75  199
 14  1003    小辉  2022-04-13  94  293
 11  1004    小猛  2022-05-10  12  12
 13  1004    小猛  2022-06-12  80  92

在此查询中,我们使用ROWS BETWEEN子句来指定窗口,该窗口从unbounded preceding(即第一行)到当前行。这将导致窗口中只包含当前行及以上的所有行

注意,此查询假定窗口按照user_id列升序排列。如果窗口按照其他列或降序排序,则需要相应更改窗口规范。

滑动求和(指定开窗聚合的行)

sum(需要求和的列) over(partition by 分组列 order by 排序列 range between ... and ...)

sum(需要求和的列) over(partition by 分组列 rows between ... and ...)

  • range 当前值 rows当前行

  • 指定聚合行的范围, 配合

     order by

    使用

    • current row: 当前行

    • rows between and :指定窗口的大小

    • n FOLLOWING: 往后 n 行数据

    • n preceding: 往前n 行数据

    • UNBOUNDED PRECEDING 表示从前面的起点 第一行

    • UNBOUNDED FOLLOWING 表示到后面的终点 最后一行

 select  *,sum(order_amount ) over(partition by user_id  order by order_date rows between 1 preceding and current row  )
 from order_info
1	1001	小元	2022-01-01	10	10
5	1001	小元	2022-01-05	46	56
8	1001	小元	2022-01-08	50	96
  • 需要注意的是 在有同行数据相同时 使用range 会出现以下结果 因为range是当前值之前的数据

    小红  100  200
    小李  100  200
    小赵  300  500
    

hive开窗函数进阶 - bitbitbyte - 博客园 (cnblogs.com)

多行变多列和多列转多行

多行转多列使用case when 方法

id  userid subject score
1	001	语文	90
2	001	数学	92
3	001	英语	80
4	002	语文	88
5	002	数学	90
6	002	英语	75.5
7	003	语文	70
8	003	数学	85
9	003	英语	90
10	003	政治	82

select userid,
	sum(case when subject='语文' then score else 0 end) 语文,
	sum(case when subject='数学' then score else 0 end) 数学,
	sum(case when subject='英语' then score else 0 end) 英语,
	sum(case when subject='政治' then score else 0 end) 政治
from  tb_score
group by userid

PS:因为需要的是一行数据包含多列,所以需要分组 然后做聚合操作

userid 语文 数学  英语 政治
001	90	92	80	  0
002	88	90	75.5	  0
003	70	85	90   82

多列转多行使用union all方法

select  userid, "语文"  course, cn_score score from tb_score1
union all
select  userid, "数学"  course, cn_score score from tb_score1
union all
select  userid, "英语"  course, en_score score from tb_score1
union all
select  userid, "政治"  course, po_score score from tb_score1
001	语文	90
002	语文	88
003	语文	70
001	数学	90
002	数学	88
003	数学	70
001	英语	80
002	英语	75.5
003	英语	90
001	政治	0
002	政治	0
003	政治	82

附:UNION与UNION ALL的区别(摘):

1.对重复结果的处理:UNION会去掉重复记录,UNION ALL不会; 2.对排序的处理:UNION会排序,UNION ALL只是简单地将两个结果集合并; 3.效率方面的区别:因为UNION 会做去重和排序处理,因此效率比UNION ALL慢很多; ———————————————— MySql 动态多列转多行_mysql 多行转多列-CSDN博客

连续多天登录

思路:

  • 因为id唯一, 通过对数据进行开窗排序,得到连续且不相同的顺序序号(所以需要使用row_number()),

  • id-序号 当连续出现时 id递增1 排序序号递增1 这个值就一定会相同 统计相同值的个数 就是连续出现的个数 本例子连续的是id 具体题目要选取合适的连续字段

logs表
id  num
1	1
2	1
3	1
4	2
5	1
6	2
7	2            查找所有至少连续出现三次的数字。
select num
from(
		select *,id-(rank() over(partition by num order by id)) rk
		from logs ) t 
group by  rk,num
having count(*)>=3

踩坑

开窗函数为聚合函数时,加order by 与不加 order by的区别

当为排序函数,如row_number(),rank()等时,over中的order by只起到窗口内排序作用。

当为聚合函数,如max,min,count等时,over中的order by不仅起到窗口内排序,还起到窗口内从当前行到之前所有行的聚合(多了一个范围)。

select  *,sum(order_amount ) over(partition by user_id   )
from order_info
8	1001	小元	2022-01-08	50	171
3	1001	小元	2022-02-03	23	171
5	1001	小元	2022-01-05	46	171
6	1001	小元	2022-04-06	42	171
1	1001	小元	2022-01-01	10	171
7	1002	小海	2022-01-07	50	94
4	1002	小海	2022-01-04	29	94
2	1002	小海	2022-01-02	15	94
12	1003	小辉	2022-04-11	75	293
14	1003	小辉	2022-04-13	94	293
9	1003	小辉	2022-04-08	62	293
10	1003	小辉	2022-04-09	62	293
11	1004	小猛	2022-05-10	12	92
13	1004	小猛	2022-06-12	80	92
select  *,sum(order_amount ) over(partition by user_id order by order_date  )
from order_info
1	1001	小元	2022-01-01	10	10
5	1001	小元	2022-01-05	46	56
8	1001	小元	2022-01-08	50	106
3	1001	小元	2022-02-03	23	129
6	1001	小元	2022-04-06	42	171
2	1002	小海	2022-01-02	15	15
4	1002	小海	2022-01-04	29	44
7	1002	小海	2022-01-07	50	94
9	1003	小辉	2022-04-08	62	62
10	1003	小辉	2022-04-09	62	124
12	1003	小辉	2022-04-11	75	199
14	1003	小辉	2022-04-13	94	293
11	1004	小猛	2022-05-10	12	12
13	1004	小猛	2022-06-12	80	92

发现不加order by order_date的话,就是针对一整个分区进行sum求和。加上order by order_date后,就是根据当前行到之前所有行聚合

hive踩坑笔记 —— 开窗函数为聚合函数时,加order by 与不加 order by的区别_一纸春秋的博客-CSDN博客

  • 在HDFS删除外部表的元数据却并没有删除这个表时,再次插入数据时 可能会出现 -ext-10000报错 需要将表drop 然后再次建表

  • 建mysql表时 如果数据有中文 数据库和表都需要设置utf8格式 ,可以使用navaciat 建表 也可以在建表语句时设置utf8 否则在查数据时会出现编码问题 /x8/... 这种情况

  • 开窗函数不能作为聚合函数参数 也不能作为查询条件

  • 报错:Fatal error occurred when node tried to create too many dynamic partitions. The maximum number of dynamic partitions is controlled by hive.exec.max.dynamic.partitions and hive.exec.max.dynamic.partitions.pernode. Maximum was set to 100 partitions per node, number of dynamic partitions on this node: 101

    原因:

    这个错误消息意味着节点试图创建了太多动态分区,而导了致命错误。Hive 通过控制参数 hive.exec.max.dynamic.partitionshive.exec.max.dynamic.partitions.pernode 来限制动态分区的数量,允许每个节点创建的最大分区数为 100 个。但是该节点创建的动态分区数量是 101,因此 Hive 触发了致命错误。

    要解决这个问题,可以通过以下方式之一来增加节点上可用动态分区的数量:

    1. 调整 hive.exec.max.dynamic.partitionshive.exec.max.dynamic.partitions.pernode 参数的值。可以尝试将它们的值增加到更高的数字,以使节点能够创建更多的动态分区。但需要注意的是,增加这两个参数的值也可能导致内存使用率增加,所以需要平衡资源和性能之间的关。

    2. 可以考虑使用静态分区代替动态分区。如果数据的分布情况已知,可以使用静态分区来替代动态分区。静态分区的数量是有限的,也不会导致过多的分区创建。

    3. 调整 Hive 表的分区策略。可能需要重新设计表的分区策略或者重新分区数据,以使节点上的动态分区数量降至可用范围内。

  • 2023-06-01 10:21:26,355 WARN  [main] server.HiveServer2: Error starting HiveServer2 on attempt 1, will retry in 60000ms
    java.lang.NoClassDefFoundError: org/apache/tez/dag/api/TezConfiguration
        at org.apache.hadoop.hive.ql.exec.tez.TezSessionPoolSession$AbstractTriggerValidator.

    这是在安装hbase后 hiveserver2 连接时报的错误

    解决方法:

     
    
        hive.server2.active.passive.ha.enable
        true
    
    

  • mysql hive库中的SDS DBS TABLES 存储着hive 的文件数据信息 TABLES 主表 通过外键与另两个表关联

你可能感兴趣的:(hive)