语法: if(boolean testCondition, T valueTrue, T valueFalseOrNull)
返回值: T
分析: 当条件testCondition为TRUE时,返回valueTrue;否则返回valueFalseOrNull(valueTrue,valueFalseOrNull为泛型)
hive> select if(1=1,100,200);
100
复制代码
5.2 空查找函数: nvl
语法: nvl(T value, T default_value)
返回值: T
分析: 如果value值为NULL就返回default_value,否则返回value
hive> select nvl(null,5);
5
复制代码
5.3 非空查找函数: COALESCE
语法: COALESCE(T v1, T v2,…)
返回值: T
分析: 返回参数中的第一个非空值;如果所有值都为NULL,那么返回NULL
hive> select COALESCE (NULL,44,55);
44
复制代码
5.4 条件判定函数:CASE
语法: CASE a WHEN b THEN c [WHEN d THEN e] * [ELSE f] END
返回值: T
分析: 如果a等于b,那么返回c;如果a等于d,那么返回e;否则返回f
hive> select CASE 4 WHEN 5 THEN 5 WHEN 4 THEN 4 ELSE 3 END;
4
复制代码
5.5 条件判定函数:CASE
语法: CASE WHEN a THEN b [WHEN c THEN d]* [ELSE e] END
返回值: T
分析: 如果a为TRUE,则返回b;如果c为TRUE,则返回d;否则返回e
hive> select CASE WHEN 5>0 THEN 5 WHEN 4>0 THEN 4 ELSE 0 END;
5
复制代码
5.6 空值判定函数:isnull
语法: isnull( a )
返回值: boolean
分析: 如果a为null就返回true,否则返回false
hive> select isnull(5);
false
复制代码
5.7 非空值判定函数:isnotnull
语法: isnotnull ( a )
返回值: boolean
分析: 如果a为非null就返回true,否则返回false
hive> select isnotnull(5);
true
复制代码
第6章 字符串函数
6.1 字符串长度函数:length
语法: length(string A)
返回值: int
分析:返回字符串A的长度
hive> select length('abcedfg') from iteblog;
7
复制代码
6.2 字符串反转函数:reverse
语法: reverse(string A)
返回值: string
分析:返回字符串A的反转结果
hive> select reverse(abcedfg’) from iteblog;
gfdecba
复制代码
6.3 字符串毗连函数:concat
语法: concat(string A, string B…)
返回值: string
分析:返回输入字符串毗连后的结果,支持任意个输入字符串
hive> select concat(‘abc’,'def’,'gh’) from iteblog;
abcdefgh
复制代码
6.4 带分隔符字符串毗连函数:concat_ws
语法: concat_ws(string SEP, string A, string B…)
返回值: string
分析:返回输入字符串毗连后的结果,SEP表现各个字符串间的分隔符
hive> select concat_ws(',','abc','def','gh') from iteblog;
abc,def,gh
复制代码
6.5 字符串截取函数:substr,substring
语法: substr(string A, int start),substring(string A, int start)
返回值: string
分析:返回字符串A从start位置到结尾的字符串
hive> select substr('abcde',3) from iteblog;
cde
hive> select substring('abcde',3) from iteblog;
cde
hive> select substr('abcde',-1) from iteblog; (和ORACLE相同)
e
复制代码
6.6 字符串截取函数:substr,substring
语法: substr(string A, int start, int len),substring(string A, int start, int len)
返回值: string
分析:返回字符串A从start位置开始,长度为len的字符串
hive> select substr('abcde',3,2) from iteblog;
cd
hive> select substring('abcde',3,2) from iteblog;
cd
hive>select substring('abcde',-2,2) from iteblog;
de
复制代码
6.7 字符串转大写函数:upper,ucase
语法: upper(string A) ucase(string A)
返回值: string
分析:返回字符串A的大写格式
hive> select upper('abSEd') from iteblog;
ABSED
hive> select ucase('abSEd') from iteblog;
ABSED
复制代码
6.8 字符串转小写函数:lower,lcase
语法: lower(string A) lcase(string A)
返回值: string
分析:返回字符串A的小写格式
hive> select lower('abSEd') from iteblog;
absed
hive> select lcase('abSEd') from iteblog;
absed
复制代码
6.9 去空格函数:trim
语法: trim(string A)
返回值: string
分析:去除字符串双方的空格
hive> select trim(' abc ') from iteblog;
abc
复制代码
6.10 左边去空格函数:ltrim
语法: ltrim(string A)
返回值: string
分析:去除字符串左边的空格
hive> select ltrim(' abc ') from iteblog;
abc
复制代码
6.11 右边去空格函数:rtrim
语法: rtrim(string A)
返回值: string
分析:去除字符串右边的空格
hive> select rtrim(' abc ') from iteblog;
abc
复制代码
6.12 正则表达式替换函数:regexp_replace
语法: regexp_replace(string A, string B, string C)
返回值: string
分析:将字符串A中的符合java正则表达式B的部分替换为C。留意,在有些情况下要使用转义字符,雷同oracle中的regexp_replace函数。
hive> select regexp_replace('foobar', 'oo|ar', '') from iteblog;
fb
复制代码
6.13 正则表达式解析函数:regexp_extract
语法: regexp_extract(string subject, string pattern, int index)
返回值: string
分析:将字符串subject按照pattern正则表达式的规则拆分,返回index指定的字符。
hive> select regexp_extract('foothebar', 'foo(.*?)(bar)', 1) from iteblog;
the
hive> select regexp_extract('foothebar', 'foo(.*?)(bar)', 2) from iteblog;
bar
hive> select regexp_extract('foothebar', 'foo(.*?)(bar)', 0) from iteblog;
语法: instr(string str, string substr)
返回值: int
分析:查找字符串str中子字符串substr出现的位置,如果查找失败将返回0,如果任一参数为Null将返回null,留意位置为从1开始的
hive> select instr(‘dvfgefggdgaa’,‘aa’);
11
复制代码
6.30 第一次出现的位置:locate
语法: locate(string substr, string str[, int pos])
返回值: int
分析:查找字符串str中的pos位置后字符串substr第一次出现的位置
hive> select locate(‘aa’,‘aabbedfaad’,2);
8
复制代码
6.31 返回出现次数TOP K的的子序列:ngrams
语法: ngrams(array, int N, int K, int pf)
返回值: array<struct<string,double>>
分析:返回出现次数TOP K的的子序列,n表现子序列的长度,详细看StatisticsAndDataMining (这里的表明更易懂)
6.32 printf风格格式输出字符串:printf
语法:printf(String format, Obj… args)
返回值: string
分析:按照printf风格格式输出字符串
order by表现窗口内按什么排序,如果只有over表现直接最大窗口排序;如果有partition by每个细窗口单独排序。
窗口子句,可以进一步限定范围
(rows | range) between (unbounded | [num]) preceding and ([num] preceding | current row | (unbounded | [num]) following
(rows | range) between current row and (current row | (unbounded | [num]) following)
(rows | range) between [num] following and (unbounded | [num]) following
rows between unbounded preceding and unbounded following
行的范围为上无边界到下无边界(第一行到末了一行)。
注:窗口函数是一行一行执行的。
load data local inpath "/opt/module/hive/datas/business.txt"
into table business;
复制代码
12.9.1 案例演示
购买过的总人次并保存所有信息
hive>
select
name,
orderdate,
cost,
count(*)over(rows between unbounded preceding and unbounded following) cn
from
business;
结果:
name orderdate cost cn
小辉 2022-04-13 94 14
小猛 2022-06-12 80 14
小辉 2022-04-11 75 14
小猛 2022-05-10 12 14
小辉 2022-04-09 62 14
小辉 2022-04-08 62 14
小元 2022-01-08 50 14
小海 2022-01-07 50 14
小元 2022-04-06 42 14
小元 2022-01-05 46 14
小海 2022-01-04 29 14
小元 2022-02-03 23 14
小海 2022-01-02 15 14
小元 2022-01-01 10 14
复制代码
购买过的累加人次并保存所有信息
hive>
select
name,
orderdate,
cost,
count(*)over(rows between unbounded preceding and current row)cn
from
business;
结果:
name orderdate cost cn
小辉 2022-04-13 94 1
小猛 2022-06-12 80 2
小辉 2022-04-11 75 3
小猛 2022-05-10 12 4
小辉 2022-04-09 62 5
小辉 2022-04-08 62 6
小元 2022-01-08 50 7
小海 2022-01-07 50 8
小元 2022-04-06 42 9
小元 2022-01-05 46 10
小海 2022-01-04 29 11
小元 2022-02-03 23 12
小海 2022-01-02 15 13
小元 2022-01-01 10 14
复制代码
购买过的总人数
hive>
select
name,
count(*)over(rows between unbounded preceding and unbounded following)cn
from
business
group by
name;
结果:
name cn
小辉 4
小猛 4
小海 4
小元 4
复制代码
注:窗口函数的执行序次是在group by之后。
4) 购买过的累加人数
hive>
select
name,
count(*)over(rows between unbounded preceding and current row)
from
business
group by
name;
结果:
name cn
小辉 1
小猛 2
小海 3
小元 4
复制代码
2022年4月份购买过的顾客及总人数
(1)写法1
hive>
select
name,
count(*) over (rows between unbounded preceding and unbounded following) cn
from
business
where
substring(orderdate,1,7) = '2022-04'
group by
name;
结果:
name cn
小辉 2
小元 2
复制代码
(2)写法2
hive>
select
name,
count(*) over () cn
from
business
where
substring(orderdate,1,7) = '2022-04'
group by
name;
结果:
name cn
小辉 2
小元 2
复制代码
能发现窗口子句加与不加结果是同等,缘故原由是窗口子句有默认值。
When ORDER BY is specified with missing WINDOW clause, the WINDOW specification defaults to RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.
当有order by 但是缺少窗口子句时,范围是上无边界到当前行。
When both ORDER BY and WINDOW clauses are missing, the WINDOW specification defaults to ROW BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING.
当order by和窗口子句都缺少时,范围,上无边界到下无边界。
思索题:如果不用窗口函数的情况下,怎么得到以下结果?
date name_list cn
2022-01 ["小元","小海"] 2
2022-02 ["小元"] 1
2022-04 ["小元","小辉"] 2
2022-05 ["小猛"] 1
2022-06 ["小猛"] 1
复制代码
查询顾客的购买明细及月购买总额
hive>
select
name,
orderdate,
cost,
sum(cost)over(partition by month(orderdate))
from
business
结果:
name orderdate cost sum
小元 2022-01-01 10 200
小元 2022-01-08 50 200
小海 2022-01-07 50 200
小元 2022-01-05 46 200
小海 2022-01-04 29 200
小海 2022-01-02 15 200
小元 2022-02-03 23 23
小辉 2022-04-13 94 335
小元 2022-04-06 42 335
小辉 2022-04-11 75 335
小辉 2022-04-09 62 335
小辉 2022-04-08 62 335
小猛 2022-05-10 12 12
小猛 2022-06-12 80 80
复制代码
查询每个顾客的购买明细及购买总额
hive>
select
name,
orderdate,
cost,
sum(cost)over(partition by name)
from
business
结果:
name orderdate cost sum
小元 2022-01-08 50 171
小元 2022-02-03 23 171
小元 2022-01-05 46 171
小元 2022-04-06 42 171
小元 2022-01-01 10 171
小海 2022-01-07 50 94
小海 2022-01-04 29 94
小海 2022-01-02 15 94
小猛 2022-05-10 12 92
小猛 2022-06-12 80 92
小辉 2022-04-11 75 293
小辉 2022-04-13 94 293
小辉 2022-04-08 62 293
小辉 2022-04-09 62 293
复制代码
查询每个顾客每个月的购买明细及购买总额
hive>
select
name,
orderdate,
cost,
sum(cost)over(partition by name,month(orderdate))
from
business
结果:
name orderdate cost sum
小元 2022-01-08 50 106
小元 2022-01-05 46 106
小元 2022-01-01 10 106
小元 2022-02-03 23 23
小元 2022-04-06 42 42
小海 2022-01-07 50 94
小海 2022-01-04 29 94
小海 2022-01-02 15 94
小猛 2022-05-10 12 12
小猛 2022-06-12 80 80
小辉 2022-04-11 75 293
小辉 2022-04-13 94 293
小辉 2022-04-08 62 293
小辉 2022-04-09 62 293
复制代码
按照日期将cost累加并保存明细
hive>
select
name,
orderdate,
cost,
sum(cost)over(order by orderdate)
from
business
结果:
name orderdate cost sum
小元 2022-01-01 10 10
小海 2022-01-02 15 25
小海 2022-01-04 29 54
小元 2022-01-05 46 100
小海 2022-01-07 50 150
小元 2022-01-08 50 200
小元 2022-02-03 23 223
小元 2022-04-06 42 265
小辉 2022-04-08 62 327
小辉 2022-04-09 62 389
小辉 2022-04-11 75 464
小辉 2022-04-13 94 558
小猛 2022-05-10 12 570
小猛 2022-06-12 80 650
复制代码
按照日期将每个顾客cost累加并保存明细
hive>
select
name,
orderdate,
cost,
sum(cost)over(partition by name order by orderdate)
from
business
结果:
name orderdate cost sum
小元 2022-01-01 10 10
小元 2022-01-05 46 56
小元 2022-01-08 50 106
小元 2022-02-03 23 129
小元 2022-04-06 42 171
小海 2022-01-02 15 15
小海 2022-01-04 29 44
小海 2022-01-07 50 94
小猛 2022-05-10 12 12
小猛 2022-06-12 80 92
小辉 2022-04-08 62 62
小辉 2022-04-09 62 124
小辉 2022-04-11 75 199
小辉 2022-04-13 94 293
复制代码
求出每个顾客上一次和当前一次消耗的和并保存明细
hive>
select
name,
orderdate,
cost,
sum(cost)over(partition by name order by orderdate rows between 1 preceding and current row)
lag(orderdate,1,'0000-00-00')over(partition by name order by orderdate) prev_time,
lead(orderdate,1,'9999-99-99')over(partition by name order by orderdate) next_time
from
business
结果:
name orderdate cost prev_time next_time
小元 2022-01-01 10 0000-00-00 2022-01-05
小元 2022-01-05 46 2022-01-01 2022-01-08
小元 2022-01-08 50 2022-01-05 2022-02-03
小元 2022-02-03 23 2022-01-08 2022-04-06
小元 2022-04-06 42 2022-02-03 9999-99-99
小海 2022-01-02 15 0000-00-00 2022-01-04
小海 2022-01-04 29 2022-01-02 2022-01-07
小海 2022-01-07 50 2022-01-04 9999-99-99
小猛 2022-05-10 12 0000-00-00 2022-06-12
小猛 2022-06-12 80 2022-05-10 9999-99-99
小辉 2022-04-08 62 0000-00-00 2022-04-09
小辉 2022-04-09 62 2022-04-08 2022-04-11
小辉 2022-04-11 75 2022-04-09 2022-04-13
小辉 2022-04-13 94 2022-04-11 9999-99-99
复制代码
注:并不是所有函数都需要写窗口子句。
rank dense_rank ntile row_number lag lead 这些函数不支持窗口子句。
13) 查询顾客每个月第一次的购买时间 和 每个月的末了一次购买时间
hive>
select
name,
orderdate,
cost,
first_value(orderdate)over(partition by name,month(orderdate) order by orderdate rows between UNBOUNDED PRECEDING and UNBOUNDED following) first_value,
last_value(orderdate)over(partition by name,month(orderdate) order by orderdate rows between UNBOUNDED PRECEDING and UNBOUNDED following) last_value
from
business
结果:
name orderdate cost first_value last_value
小元 2022-01-01 10 2022-01-01 2022-01-08
小元 2022-01-05 46 2022-01-01 2022-01-08
小元 2022-01-08 50 2022-01-01 2022-01-08
小元 2022-02-03 23 2022-02-03 2022-02-03
小元 2022-04-06 42 2022-04-06 2022-04-06
小海 2022-01-02 15 2022-01-02 2022-01-07
小海 2022-01-04 29 2022-01-02 2022-01-07
小海 2022-01-07 50 2022-01-02 2022-01-07
小猛 2022-05-10 12 2022-05-10 2022-05-10
小猛 2022-06-12 80 2022-06-12 2022-06-12
小辉 2022-04-08 62 2022-04-08 2022-04-13
小辉 2022-04-09 62 2022-04-08 2022-04-13
小辉 2022-04-11 75 2022-04-08 2022-04-13
小辉 2022-04-13 94 2022-04-08 2022-04-13
复制代码
查询前20%时间的订单信息
hive>
-- 将数据分为5组
select
name,
orderdate,
cost,
ntile(5)over(order by orderdate) n_g
from
business t1
-- 拿到5组中的第一组
select
*
from (
select
name,
orderdate,
cost,
ntile(5)over(order by orderdate) n_g
from
business
)t1
where t1.n_g=1
结果:
name orderdate cost n_g
小元 2022-01-01 10 1
小海 2022-01-02 15 1
小海 2022-01-04 29 1
复制代码
按照花费的金额进行排名
hive>
select
name,
orderdate,
cost,
rank()over(order by cost desc) rk,
dense_rank()over(order by cost desc) drk,
row_number()over(order by cost desc) drk
from
business
结果:
name orderdate cost rk drk rrk
小辉 2022-04-13 94 1 1 1
小猛 2022-06-12 80 2 2 2
小辉 2022-04-11 75 3 3 3
小辉 2022-04-08 62 4 4 4
小辉 2022-04-09 62 4 4 5
小海 2022-01-07 50 6 5 6
小元 2022-01-08 50 6 5 7
小元 2022-01-05 46 8 6 8
小元 2022-04-06 42 9 7 9
小海 2022-01-04 29 10 8 10
小元 2022-02-03 23 11 9 11
小海 2022-01-02 15 12 10 12
小猛 2022-05-10 12 13 11 13
小元 2022-01-01 10 14 12 14
复制代码
注:排名分析函数中不需要写参数,会将排好序数据进行标号。
按照每个顾客花费的金额进行排名
hive>
select
name,
orderdate,
cost,
rank()over(partition by name order by cost desc) rk,
dense_rank()over(partition by name order by cost desc) drk,
row_number()over(partition by name order by cost desc) drk
from
business
结果:
name orderdate cost rk drk rrk
小元 2022-01-08 50 1 1 1
小元 2022-01-05 46 2 2 2
小元 2022-04-06 42 3 3 3
小元 2022-02-03 23 4 4 4
小元 2022-01-01 10 5 5 5
小海 2022-01-07 50 1 1 1
小海 2022-01-04 29 2 2 2
小海 2022-01-02 15 3 3 3
小猛 2022-06-12 80 1 1 1
小猛 2022-05-10 12 2 2 2
小辉 2022-04-13 94 1 1 1
小辉 2022-04-11 75 2 2 2
小辉 2022-04-08 62 3 3 3
小辉 2022-04-09 62 3 3 4
复制代码
第13章 高级聚合函数
13.1 collect_list
collect_list 收集并形成list集合,结果不去重
hive>
select
sex,
collect_list(job)
from
employee
group by
sex
复制代码
结果:
女 ["行政","研发","行政","前台"]
男 ["销售","研发","销售","前台"]
复制代码
13.2 collect_set
collect_set 收集并形成set集合,结果去重
hive>
select
sex,
collect_set(job)
from
employee
group by
sex
结果:
女 ["行政","研发","前台"]
男 ["销售","研发","前台"]
复制代码
13.3 炸裂函数
一进多出(一行进入,多行输出)。
explode 将数组或者map展开
hive> select explode(array('a','b','d','c'));
结果:
a
b
d
c
复制代码
-- 炸裂与侧写结合
-- 用法:lateral view udtf(expression) tableAlias AS columnAlias