当前位置:   article > 正文

【Hive】大数据的排序和拼接_hive排序拼接

hive排序拼接

目录

一、前言

二、样例SQL

三、函数用法

四、思路解析


一、前言

大数据开发中有时会有这样的需求:将多条数据中的某个字段通过排序拼接为一个字段。

  1. name oid
  2. 赵一 80
  3. 钱二 190
  4. 孙三 40
  5. 得到结果:190|80|40

二、样例SQL

  1. select
  2. regexp_replace (concat_ws("|",sort_array (collect_set (concat_ws(":",concat(IF (order_id< 10,"000",IF (order_id< 100,"00",IF (order_id< 1000,"0",""))),order_id),oid)))),"\\d+\:","") oids
  3. from
  4. (select
  5. oid,
  6. row_number() over (PARTITION BY name ORDER BY oid DESC) order_id
  7. from a) a;

三、函数用法

  1. 1.regexp_replace(source, pattern, replace_string, occurrence)
  2. ● source:string类型,要替换的原始字符串。
  3. ● pattern:string类型常量,要匹配的正则模式,pattern为空串时抛异常。
  4. ● replace_string:string,将匹配的pattern替换成的字符串。
  5. ● occurrence:bigint类型常量,必须大于等于0,默认是0,大于0:表示将第几次匹配替换成replace_string,等于0:表示替换掉所有的匹配子串。其它类型或小于0抛异常。
  6. 2.concat_ws(separator,str1,str2,…)
  7. concat_ws() 代表concat with separator,是concat()的特殊形式。第一个参数separator是其它参数的分隔符。会忽略所有的NULL值。
  8. 3.concat(str1,str2,…)
  9. 直接将参数拼接起来,和concat_ws的区别是没有专门放分隔符的参数。
  10. 4.sort_array
  11. 将列表进行升序排序
  12. 排序逻辑为按字母序排序,也就是说10会排在2之前。
  13. 5.collect_set
  14. 返回一个数组或者说是列转行,去除重复元素,与sort_array搭配可以实现升序排序。
  15. 6.collect_list
  16. 返回一个数组或者说是列转行,不去除重复元素,与sort_array搭配可以实现升序排序。
  17. 7.row_number() over (PARTITION BY X ORDER BY Y DESC)
  18. 具有分组排序的功能
  19. PARTITION BY:用于给结果集分组
  20. ORDER BY:排序

四、思路解析

1.在内层SQL中获取到oid字段以及排序字段order_id。

  1. select
  2. oid,
  3. row_number() over (PARTITION BY name ORDER BY oid DESC) order_id
  4. from a
  5. 80 2
  6. 190 1
  7. 40 3

2.但是order_id不能直接用于排序拼接,原因是排序函数sort_array的排序逻辑是字母序升序排序,也就是10会排在2之前,因为10的首位1要比2小。所以这里用到concat将order_id填充成一个四位数字,10填充为0010,2填充为0002。这样我们就有了排序字段。

concat(IF (order_id< 10,"000",IF (order_id< 100,"00",IF (order_id< 1000,"0",""))),order_id)

3.将排序字段和结果字段oid用冒号作为分隔符拼接在一起。

  1. concat_ws(":",concat(IF (order_id< 10,"000",IF (order_id< 100,"00",IF (order_id< 1000,"0",""))),order_id),oid)
  2. 0002:80
  3. 0001:190
  4. 0003:40

4.将排序字段和结果字段拼接之后的字段升序排序。这里的升序排序是按照冒号之前的四位数来排序的。用到函数sort_array、collect_set或者collect_list。

  1. sort_array (collect_set (concat_ws(":",concat(IF (order_id< 10,"000",IF (order_id< 100,"00",IF (order_id< 1000,"0",""))),order_id),oid)))
  2. 0001:190
  3. 0002:80
  4. 0003:40

5.将升序排序之后的数据拼接起来。

  1. concat_ws("|",sort_array (collect_set (concat_ws(":",concat(IF (order_id< 10,"000",IF (order_id< 100,"00",IF (order_id< 1000,"0",""))),order_id),oid))))
  2. 0001:190|0002:80|0003:40

6.将四位数和冒号替换为空。到这一步就得到了想要的结果。

  1. regexp_replace (concat_ws("|",sort_array (collect_set (concat_ws(":",concat(IF (order_id< 10,"000",IF (order_id< 100,"00",IF (order_id< 1000,"0",""))),order_id),oid)))),"\\d+\:","")
  2. 190|80|40

7.如果想得到40|80|190的结果就把内层SQL中的order_id升序排列。

  1. select
  2. oid,
  3. row_number() over (PARTITION BY name ORDER BY oid ASC) order_id
  4. from a
  5. 80 2
  6. 190 3
  7. 40 1

8.需要注意的是oid不能为NULL,否则与四位数的order_id拼接之后就只剩下四位数。得不到最终想要的拼接结果。

  1. concat_ws(':',0001,NULL)
  2. 得到结果是0001

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号