[hive]collect_set排序问题

1、原始表

select zheng_shi_indicator,guo_biao_di_yu_dai_ma,areas,years from test.test_formal_edu

 2、需求

结果格式:

第一列:正式指标   

第二列:该指标下的所有地区名称,按照国标地域代码升序排序,按照";"进行分割,且该字段不为空时,末尾追加";"。

第三列:该指标下所有的年份,按字母顺序排序,按照";"进行分割,且该字段不为空时,末尾追加";"。

3、思路

处理年份很简单collect_set+sort_array就行了

处理地区,难在要按照地区代码的顺序将地区名称进行排序,可以使用下面的语句:

在over中按照地区代码进行排序,然后在collect_set中把排好顺序的数据收集起来。

collect_set(areas) 
over(partition by zheng_shi_indicator 
order by guo_biao_di_yu_dai_ma asc 
rows between unbounded preceding and current row) areas_sort

但是结果会是这样的:

  即:collect_set(a) over(partition by b order by c) 集合中的数据a会按照 c列的顺序 按行累加

如何处理这个问题呢?本身也是需要按照指标进行去重的,在这里我们选择最长的一条进行去重,就可以解决问题了,最长的那条涵盖了所有的数据。

4、实现

insert overwrite table test.test_formal_edu_res1
select
zheng_shi_indicator,
areas_str,
year_str
from
(
    select
    zheng_shi_indicator,
    areas_str,
    year_str,
    row_number() over (partition by zheng_shi_indicator order by length(areas_str) desc) rn
    from
    (
        select
        zheng_shi_indicator,
        if(areas_str!="",concat(areas_str,";"),areas_str)areas_str,
        if(year_str!="",concat(year_str,";"),year_str)year_str
        from
        (
            select
            zheng_shi_indicator,
            concat_ws(";",areas_sort)areas_str,
            concat_ws(";",year_sort)year_str
            from
            (
                select
                zheng_shi_indicator,
                areas_sort,
                sort_array(years_set) year_sort
                from
                (
                    select
                    zheng_shi_indicator,
                    collect_set(areas) over(partition by zheng_shi_indicator order by guo_biao_di_yu_dai_ma asc rows between unbounded preceding and current row) areas_sort,
                    collect_set(years) over(partition by zheng_shi_indicator) years_set
                    from
                    test.test_formal_edu
                    where nian_jian_zhong_wen_ming="中国教育统计年鉴"
                )t1
            )t2
        )t3
    )t4
)t5
where rn=1
;

### 回答1: Hivecollect_set函数是用来将一列数据中的重复值去重后,将结果以集合的形式返回。如果需要对返回的集合进行排序,可以使用Hive的sort_array函数,将集合转换为数组后进行排序。具体操作如下: 1. 使用collect_set函数将需要去重的列转换为集合: ``` SELECT collect_set(column_name) FROM table_name; ``` 2. 使用sort_array函数将集合转换为数组并排序: ``` SELECT sort_array(collect_set(column_name)) FROM table_name; ``` 其中,column_name为需要去重并排序的列名,table_name为数据表名。 ### 回答2: Hivecollect_set 函数可以用于将某个字段的数据进行集合操作,将相同的值合并为一个集合,并返回一个数组。但是,由于集合是无序的,因此如果需要对这个数组进行排序,就需要使用 Hive 中的 sort_array 函数进行排序操作。 sort_array 函数需要一个数组作为参数,并返回一个排序后的数组。可以将 collect_set 函数的结果作为 sort_array 函数的参数,即可得到排序后的结果。下面是一个示例代码: SELECT sort_array(collect_set(col1)) FROM my_table; 其中,col1 表示需要进行集合和排序的字段名,my_table 表示需要查询的表名。 需要注意的是,sort_array 函数默认是按照升序进行排序的。如果需要降序排序,则需要在 sort_array 函数的参数中添加 DESC 关键字,如下所示: SELECT sort_array(collect_set(col1) DESC) FROM my_table; 这样可以得到按照字段 col1 降序排列的集合结果。另外,如果需要按照别的字段进行排序,可以在 collect_set 函数的参数中添加 ORDER BY 关键字,如下所示: SELECT sort_array(collect_set(col1 ORDER BY col2)) FROM my_table; 其中,col2 表示用于排序的字段名。这样可以得到按照字段 col2 进行排序后的集合结果。 ### 回答3: collect_setHive提供的一种聚合函数,其作用是将指定列中的唯一值收集到一个集合中。由于集合具有无序性,所以collect_set函数不会对结果进行排序。但是在某些场景下,我们需要对集合中的元素进行排序,这时需要借助于其他的函数或技巧。 方法1:使用sort_array函数 sort_array函数可以对数组类型列进行排序,因此我们可以先将collect_set的结果转换为数组,然后对数组进行排序。示例代码如下: ``` SELECT sort_array(collect_set(col1)) FROM table_name; ``` 该语句将table_name表中col1列的唯一值收集到一个集合中,并对集合中的元素进行排序。 方法2:使用LATERAL VIEW和explode函数 LATERAL VIEW和explode函数可以将一个复杂类型的列转换为多行记录,我们可以使用这种方式来实现排序。示例代码如下: ``` SELECT t.col1_sorted FROM ( SELECT explode(collect_set(col1)) as col1_sorted FROM table_name ) t ORDER BY t.col1_sorted; ``` 该语句首先使用collect_set函数将table_name表中col1列的唯一值收集到一个集合中,然后使用explode函数将集合转换为多行记录,并给新列取名为col1_sorted。最后使用ORDER BY对新列进行排序。 方法3:使用外部程序进行排序 如果数据量较小,我们可以将查询结果导出到本地文件系统中,然后使用外部程序(如Linux的sort命令)进行排序,最后再导入到Hive表中。示例代码如下: ``` INSERT OVERWRITE LOCAL DIRECTORY '/tmp/result' SELECT collect_set(col1) FROM table_name; !sort /tmp/result/* > /tmp/result_sorted CREATE EXTERNAL TABLE table_name_sorted ( col1 array<string> ) LOCATION '/tmp/result_sorted'; LOAD DATA LOCAL INPATH '/tmp/result_sorted' INTO TABLE table_name_sorted; ``` 该语句首先使用collect_set函数将table_name表中col1列的唯一值收集到一个集合中,并将结果导出到本地目录/tmp/result下。然后使用Linux的sort命令对/tmp/result下的文件进行排序,最后导入到新建的外部表table_name_sorted中。注意,为了保证集合中的元素是字符串类型,需要将新建表的col1列定义为array<string>。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值