hive sql中常用技巧

目录

    • sort_array
    • 分析函数
      • analytic_function_name为聚合函数
      • rank()、dense_rank()、row_number()
      • first_value()和 last_value()
      • lead()和lag()
    • regexp_extract
    • concat()、concat_ws()、group_concat()、collset_set()
    • keyvalue
    • 优化相关
      • distribute by+sort by V.S order by
      • group by V.S count(distinct)
      • map join

sort_array

函数声明如下:ARRAY sort_array(ARRAY)
函数用途:对给定中的数组排序
参数说明:ARRAY,ARRAY类型数据,数组中的数据可为任意类型。
返回值:ARRAY类型
示例:

--建表
CREATE TABLE sort_array
(
    c1 ARRAY<STRING>
    ,c2 ARRAY<INT>
)
;

--装载数据
INSERT OVERWRITE TABLE sort_array
SELECT  array('d','c','b','a')  AS c1
        ,array(4,3,2,1)         AS c2
;

--查询
SELECT  sort_array(c1)
        ,sort_array(c2)
FROM    sort_array
;

--结果

["a","b","c","d"] [1,2,3,4]

分析函数

基本语法:

analytic_function_name([argument_list]) 
OVER ([PARTITION BY partition_expression,]
[ORDER BY sort_expression,[ASC|DESC]])
  • analytic_function_name: 函数名称 — 比如 RANK(), SUM(), FIRST_VALUE()等等
  • partition_expression: 分区列
  • sort_expression: 排序列

analytic_function_name为聚合函数

聚合函数可为sum、avg、count、max、min,如下:

select *,
   sum(成绩) over (order by 学号) as current_sum,
   avg(成绩) over (order by 学号) as current_avg,
   count(成绩) over (order by 学号) as current_count,
   max(成绩) over (order by 学号) as current_max,
   min(成绩) over (order by 学号) as current_min
from 班级表

结果:
hive sql中常用技巧_第1张图片
以sum为例,如上图,聚合函数sum在窗口函数中,是对自身记录、及位于自身记录以上的数据进行求和的结果。比如0004号,在使用sum窗口函数后的结果,是对0001,0002,0003,0004号的成绩求和,若是0005号,则结果是0001号~0005号成绩的求和,以此类推。
不仅是sum求和,avg平均、count计数、max最大值、min最小值,也是同理,都是针对自身记录、以及自身记录之上的所有数据进行计算。
比如0005号后面的聚合窗口函数结果是:学号0001~0005五人成绩的总和、平均、计数及最大最小值。如果想要知道所有人成绩的总和、平均等聚合结果,看最后一行即可。
这样窗口函数有什么用?
聚合函数作为窗口函数,可以在每一行的数据里直观的看到,截止到本行数据,统计数据是多少(最大值、最小值等)。同时可以看出每一行数据,对整体统计数据的影响。
Attention:
sum( col ) over (partition by 分区 order by 排序 desc rows BETWEEN unbounded preceding AND current row
unbounded:无界限
preceding:从分区第一行头开始,则为 unbounded。 N为:相对当前行向前的偏移量
following :与preceding相反,到该分区结束,则为 unbounded。N为:相对当前行向后的偏移量
current row:顾名思义,当前行,偏移量为0

rank()、dense_rank()、row_number()

rank:对组中的数据进行排名,如果名次相同,则排名也相同,但是下一个名次的排名序号会出现不连续。比如查找具体条件的topN行。rank() 排序为 (1,2,2,4),简称并列跳跃
dense_rank:dense_rank函数的功能与rank函数类似,dense_rank函数在生成序号时是连续的,而rank函数生成的序号有可能不连续。当出现名次相同时,则排名序号也相同。而下一个排名的序号与上一个排名序号是连续的。dense_rank()排序为(1,2,2,3),简称并列不跳跃
row_number:row_number函数在生成序号时是连续的,当出现名次相同,排名序号也是连续的。row_number()排序为(1,2,3,4),简称不并列

first_value()和 last_value()

  • first_value:取分组内排序后,截止到当前行,第一个值。
  • last_value:取分组内排序后,截止到当前行,最后一个值。
    例如,select datediff(order_date, first_value ( order_date ) over ( partition by cust_code order by order_date )) next_order_gap from orders
    解决的问题如,客户首次购买后多少天才进行下一次购买。

lead()和lag()

  • lead(value_expr[,offset[,default]]):用于统计窗口内往下第n行值。第一个参数为列名,第二个参数为往下第n行(可选,默认为1),第三个参数为默认值(当往下第n行为NULL时候,取默认值,如不指定,则为NULL)。
  • lag(value_expr[,offset[,default]]): 与lead相反,用于统计窗口内往上第n行值。第一个参数为列名,第二个参数为往上第n行(可选,默认为1),第三个参数为默认值(当往上第n行为NULL时候,取默认值,如不指定,则为NULL)。

regexp_extract

  • 命令格式
    string regexp_extract(string , string [, bigint ])
  • 命令说明
    将字符串source按照pattern的规则拆分为组,返回第occurrence个组的字符串。
  • 参数说明
    source:必填。STRING类型,待拆分的字符串。
    pattern:必填。STRING类型常量或正则表达式。待匹配的模型。
    occurrence:可选。BIGINT类型常量,必须大于等于0。
  • 返回值说明
    返回STRING类型。返回规则如下:
    • 如果pattern为空串或pattern中没有分组,返回报错。
    • occurrence非BIGINT类型或小于0时,返回报错。不指定时默认为1,表示返回第一个组。如果occurrence等于0,则返回满足整个pattern的子串。
    • source、pattern或occurrence值为NULL时,返回NULL。
  • 示例
select regexp_extract('foothebar', '(foo)(.*?)(bar)', 0);     --返回foothebar
select regexp_extract('foothebar', '(foo)(.*?)(bar)', 1);     --返回foo
select regexp_extract('foothebar', '(foo)(.*?)(bar)', 2);     --返回the
select regexp_extract('foothebar', '(foo)(.*?)(bar)', 3);     --返回bar
  • Attention: 正则表达式

concat()、concat_ws()、group_concat()、collset_set()

  • concat(str,str,…)将多个字符串连接在一起,返回结果为连接参数产生的字符串,如果有任何一个参数为null,则返回值为null。hive sql 和 mysql都适用。
  • concat_ws(separator, str1, str2, …)和concat()一样,将多个字符串连接成一个字符串,但是可以一次性指定分隔符。
  • group_concat( [distinct] 要连接的字段 [order by 排序字段 asc/desc ] [separator ‘分隔符’] )将group by产生的同一个分组中的值连接起来,返回一个- 字符串结果。字段和separator ’ 分隔符 '中间没有逗号,仅适用于mysql。
  • collect_set()函数类似于group_concat(),其仅适用在hive sql中。

keyvalue

  • 命令格式
    keyvalue(string ,[string ,string ,] string )
    keyvalue(string ,string )
  • 命令说明
    将字符串str按照split1分成Key-Value对,并按split2将Key-Value对分开,返回key所对应的Value。
  • 参数说明
    key:必填。STRING类型。将字符串按照split1和split2拆分后,返回key值对应的Value。
    str:必填。STRING类型。待拆分的字符串。
    split1、split2:可选。STRING类型。用于作为分隔符的字符串,按照指定的两个分隔符拆分源字符串。如果表达式中没有指定这两项,默认split1为";“,split2为”:"。当某个被split1拆分后的字符串中有多个split2时,返回结果未定义。
  • 返回值说明
    返回STRING类型。返回规则如下:
    • split1或split2值为NULL时,返回NULL。
    • str或key值为NULL或没有匹配的key时,返回NULL。
    • 如果有多个Key-Value匹配,返回第一个匹配上的key对应的Value。
select keyvalue('0:1\;1:2', 1);  --返回2
select keyvalue('spm=123.qwe,cpn=101,act=890',',','=','spm')  ----返回123.qwe

优化相关

distribute by+sort by V.S order by

  • order by将结果按某字段全局排序,这会导致所有map端数据都进入一个reducer中,在数据量大时可能会长时间计算不完。
  • distribute by用于控制map端数据分配到reducer的key,sort by会视情况启动多个reducer进行排序,并且保证每个reducer内局部有序。

group by V.S count(distinct)

  • 当数据量级很大,用group by ,可以启动多个job
  • 数据集很小或者key的倾斜不明显时,用count(distinct),少量的reduce就可以处理

map join

  • Hive会将build table和probe table在map端直接完成join过程,消灭了reduce,效率很高。
  • 优化分组:set hive.auto.convent.join=true;
  • 优化表关联内存运行:/+MAPJOIN(t1,t3,t4)/

你可能感兴趣的:(SQL,数据分析,sql,hive)