Hive如何比较复杂数据类型
程序员文章站
2022-07-01 09:55:26
...
Hive中的复杂数据类型,比如array,struct, map能进行大小的比较吗,我们先来做实验看看结果。
Array
select
max(arr)
from (
select array(1,3,5) as arr
union all
select array(2,4,1) as arr
union all
select array(2,3,5) as arr
union all
select array(2,4,0) as arr
union all
select array(2,4,1,0) as arr
)a
的到的结果是[2,4,1,0]
Struct
select
max(str)
from (
select named_struct('a', 1, 'b', 3, 'c', 5) as str
union all
select named_struct('a', 2, 'b', 4, 'c', 1) as str
union all
select named_struct('a', 2, 'b', 3, 'c', 5) as str
union all
select named_struct('a', 2, 'b', 4, 'c', 0) as str
-- union all (struct必须结构相同才能union在一起)
-- select named_struct('a', 2, 'b', 4, 'c', 1, 'd', 0) as str
)a
得到的结果是{"a":2,"b":4,"c":1}
Map
select
max(m)
from (
select map('a', '1', 'b', '3', 'c', '5') as m
union all
select map('a', '2', 'b', '4', 'c', '1') as m
union all
select map('a', '2', 'b', '3', 'c', '5') as m
union all
select map('a', '2', 'b', '4', 'c', '0') as m
union all
select map('a', '2', 'b', '4', 'c', '1') as m
)a
这个会抛出异常:UDFArgumentTypeException Cannot support comparison of map<> type or complex type containing map<>.
那么hive内部具体是怎么进行复杂数据类型的比较的呢,通过github上hive的仓库可以看到执行比较的逻辑只有一句话ObjectInspectorUtils.compare()
>
那我们就看一下ObjectInspectorUtils
这个类里面具体的实现。
首先是compareSupported
,链接
可以看到这里面基础数据类型都是支持的,数组和结构体如果里面是基础数据类型可以支持,而MAP是不支持的,这和我们的实验结果是一致的。
Struct和Array的比较逻辑在下面一点的位置
它俩的逻辑是相似的,每个元素按照顺序进行比较,数组自然就是按照位置从小到大,结构体是按照Schema的定义顺序从左到右。如果出现不相等的情况就分出了大小;否则按照长度本身进行比较,长的大、短的小。
这一段逻辑还是非常有意思,因为平时很少会遇到对复杂数据类型进行比较的情况。了解了之后就能在一些特殊情况下应用起来,比如把每一行组装成一个struct,struct中的第一个元素放用户的访问时间,就可以用max()
找到用户的第一条访问记录而不用row_number()
窗口函数,执行效率就可能会有些许的提高。
注意这里虽然会对每一个元素进行比较,但是这里也是不行直接用来进行二级排序的~