内置函数
(1) NVL
给值为NULL的数据赋值,它的格式是NVL( value,default_value)。它的功能是如果value为NULL,则NVL函数返回default_value的值,否则返回value的值,如果两个参数都为NULL ,则返回NULL
select nvl(column, 0) from xxx;
(2)行转列
| 函数 | 描述 |
|---|---|
| CONCAT(string A/col, string B/col…) | 返回输入字符串连接后的结果,支持任意个输入字符串 |
| CONCAT_WS(separator, str1, str2,…) | 第一个参数参数间的分隔符,如果分隔符是 NULL,返回值也将为 NULL。这个函数会跳过分隔符参数后的任何 NULL 和空字符串。分隔符将被加到被连接的字符串之间。 |
| COLLECT_SET(col) | 将某字段的值进行去重汇总,产生array类型字段 |
| COLLECT_LIST(col) | 函数只接受基本数据类型,它的主要作用是将某字段的值进行不去重汇总,产生array类型字段。 |
(3)列转行(一列转多行)
Split(str, separator): 将字符串按照后面的分隔符切割,转换成字符array。
EXPLODE(col):
将hive一列中复杂的array或者map结构拆分成多行。
LATERAL VIEW
用法:LATERAL VIEW udtf(expression) tableAlias AS columnAlias
解释:lateral view用于和split, explode等UDTF一起使用,它能够将一行数据拆成多行数据,在此基础上可以对拆分后的数据进行聚合。
lateral view首先为原始表的每行调用UDTF,UDTF会把一行拆分成一或者多行,lateral view再把结果组合,产生一个支持别名表的虚拟表。
准备数据源测试
| movie | category |
|---|---|
| 《功勋》 | 记录,剧情 |
| 《战狼2》 | 战争,动作,灾难 |
SQL
SELECT movie,category_nameFROM movie_infolateral VIEWexplode(split(category,",")) movie_info_tmp AS category_name ;
测试结果
《功勋》 记录《功勋》 剧情《战狼2》 战争《战狼2》 动作《战狼2》 灾难
窗口函数
(1)OVER()
定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而变化。
(2)CURRENT ROW(当前行)
n PRECEDING:往前n行数据n FOLLOWING:往后n行数据
(3)UNBOUNDED(无边界)
UNBOUNDED PRECEDING 前无边界,表示从前面的起点UNBOUNDED FOLLOWING后无边界,表示到后面的终点
SQL案例:由起点到当前行的聚合
selectsum(money) over(partition by user_id order by pay_time rows between UNBOUNDED PRECEDING and current row)from or_order;
SQL案例:当前行和前面一行做聚合
selectsum(money) over(partition by user_id order by pay_time rows between 1 PRECEDING and current row)from or_order;
SQL案例:当前行和前面一行和后一行做聚合
selectsum(money) over(partition by user_id order by pay_time rows between 1 PRECEDING AND 1 FOLLOWING )from or_order;
SQL案例:当前行及后面所有行
selectsum(money) over(partition by user_id order by pay_time rows between current row and UNBOUNDED FOLLOWING )from or_order;
(4)LAG(col,n,default_val)
往前第n行数据,没有的话default_val
(5)LEAD(col,n, default_val)
往后第n行数据,没有的话default_val
SQL案例:查询用户购买明细以及上次的购买时间和下次购买时间
selectuser_id,,pay_time,money,lag(pay_time,1,'1970-01-01') over(PARTITION by name order by pay_time) prev_time,lead(pay_time,1,'1970-01-01') over(PARTITION by name order by pay_time) next_timefrom or_order;
(6)FIRST_VALUE(col,true/false)
当前窗口下的第一个值,第二个参数为true,跳过空值。
(7)LAST_VALUE (col,true/false)
当前窗口下的最后一个值,第二个参数为true,跳过空值。
SQL案例:查询用户每个月第一次的购买时间 和 每个月的最后一次购买时间
selectFIRST_VALUE(pay_time)over(partition by user_id,month(pay_time) order by pay_timerows between UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING) first_time,LAST_VALUE(pay_time)over(partition by user_id,month(pay_time) order by pay_time rows between UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING) last_timefrom or_order;
(8)NTILE(n)
把有序窗口的行分发到指定数据的组中,各个组有编号,编号从1开始,对于每一行,NTILE返回此行所属的组的编号。(用于将分组数据按照顺序切分成n片,返回当前切片值)
SQL案例:查询前25%时间的订单信息
select * from (select User_id,pay_time,money,ntile(4) over(order by pay_time) sortedfrom or_order) twhere sorted = 1;
4个By
(1)Order By
全局排序,只有一个Reducer。
(2)Sort By
分区内有序。
(3)Distrbute By
类似MR中Partition,进行分区,结合sort by使用。
(4) Cluster By
当Distribute by和Sorts by字段相同时,可以使用Cluster by方式。Cluster by除了具有Distribute by的功能外还兼具Sort by的功能。但是排序只能是升序排序,不能指定排序规则为ASC或者DESC。
在生产环境中Order By用的比较少,容易导致OOM。
在生产环境中Sort By+ Distrbute By用的多。
排序函数
(1)RANK()
排序相同时会重复,总数不会变
1
1
3
3
5
(2)DENSE_RANK()
排序相同时会重复,总数会减少
1
1
2
2
3
(3)ROW_NUMBER()
会根据顺序计算
1
2
3
4
5
日期函数
datediff:返回结束日期减去开始日期的天数
datediff(string enddate, string startdate)
select datediff('2021-11-20','2021-11-22')
date_add:返回开始日期startdate增加days天后的日期
date_add(string startdate, int days)
select date_add('2021-11-20',3)
date_sub:返回开始日期startdate减少days天后的日期
date_sub (string startdate, int days)
select date_sub('2021-11-22',3)
Impala(时间处理,可类比到hive可用)
1. 获取当前时间
timestamp 样式2021-12-10 04:36:48.147046000
bigint 样式 1639110956
| 函数/方法 | 输出类型 | 说明/样式 |
|---|---|---|
| current_timestamp() | timestamp | 所在时区的当前时间 |
| now() | timestamp | 所在时区的当前时间 |
| unix_timestamp() | bigint | 所在时区的当前时间戳 |
| utc_timestamp | timestamp | UTC时区的当前时间 |
| timeofday() | string | Fri Dec 10 12:39:46 2021 CST |
2. 获取时间指定单位函数
| 序号 | 函数/方法 | 输出类型 | 说明/样式 |
|---|---|---|---|
| 1 | year(timestamp/date) | int | 获取年 yyyy |
| 2 | quarter(timestamp/date) | int | 获取季节(1,2,3,4) |
| 3 | month(timestamp/date) | int | 获取月 |
| 4 | monthname(timestamp/date) | string | 获取月份名称 December |
| 5 | week(timestamp/date) | int | 获取周(1-53) |
| 6 | weekofyear(timestamp/date) | int | 获取周(1-53) |
| 7 | dayofweek(timestamp/date) | int | 获取天(本周第多少天,周日算第一天) |
| 8 | dayname(timestamp/date) | string | 获取天(星期几)Friday |
| 9 | next_day(timestamp/date, 10 | day(string)) | timestamp/date |
| 11 | day(timestamp/date) | int | 获取天(本月第多少天) |
| 12 | dayofmonth(timestamp/date) | int | 获取天(本月第多少天) |
| 13 | last_day(timestamp/date) | timestamp/date | 获取天(本月的最后一天日期) |
| 14 | dayofyear(timestamp/date) | int | 获取天(本年第多少天) |
| 15 | hour(timestamp/date) | int | 获取小时 |
| 16 | minute(timestamp date) | int | 获取分钟 |
| 17 | second(timestamp date) | int | 获取秒 |
| 18 | millisecond(timestamp date) | int | 获取毫秒 |
| 19 | extract (YEAR FROM timestamp) | bigint | 获取参数指定的时间单位 YEAR MONTH DAY HOUR MINUTE SECOND |
| 20 | date_part(‘year’,timestamp) | bigint | 获取参数指定的时间单位 YEAR MONTH DAY HOUR MINUTE SECOND |
| 21 | trunc(timestamp/date,unit) | timestamp/date | 获取截断为指定单位的时间 |
| unit | 截取说明 |
|---|---|
| SYYYY,YYYY,YEAR,SYEAR,YYY,YY,Y | 年 |
| Q | 季节 |
| MONTH,MON,MM,RM | 月 |
| WW | 最近的日期是与一年中的第一天相同的日期 |
| W | 最近的日期是与该月的第一天相同的星期几 |
| DDD,DD,J | 天 |
| DAY,DY,D | 星期几(星期一)的开始 |
| HH,HH12,HH24 | 小时 |
| MI | 分钟 |
3. 时间比较函数
| 序号 | 函数/方法 | 输出类型 | 说明/样式 |
|---|---|---|---|
| 1 | datediff(timestamp enddate,startdate) | int | 返回endDate比startDate多多少天 |
| 2 | int_months_between(timestamp t1,t2) | int | 返回两个日期相差的整数月份个数 |
| 3 | months_between(timestamp t1,t2) | double | 返回浮点数的月数相差的数 |
| 4 | date_cmp(DATE date1, DATE date2) | int | 比较是否相等,返回-1,0,1,null四种数值 |
| 5 | timestamp_cmp(timestamp t1,timestamp t2) | int | 比较是否相等,返回-1,0,1,null四种数值 |
4. 时间格式转换函数
| 序号 | 函数/方法 | 输出类型 | 说明/样式 |
|---|---|---|---|
| 1 | to_date(timestamp date) | string | 返回时间戳对应的date |
| 2 | to_timestamp(bigint unixtime) | timestamp | 返回整数对应的timestamp值 |
| 3 | to_timestamp(string date,string pattern) | timestamp | 返回字符串对应的timestamp值 |
| 4 | to_utc_timestamp(timestamp t,string timezone) | timestamp | 指定时区的时间戳转化为UTC时区的时间戳 |
| 5 | from_timestamp(timestamp t,string pattern) | string | 把timestamp按照pattern进行格式化 |
| 6 | from_timestamp(string date,string pattern) | string | 把date按照pattern进行格式化 |
| 7 | from_unixtime(bigint unixtime) | string | 把时间戳秒数转化为本地地区中的字符串 |
| 8 | from_unixtime(bigint unixtime,string pattern) | string | 时间戳转化为本地时区字符串,pattern格式 |
| 9 | from_utc_timestamp(timestamp t,string timezone) | timestamp | UTC时区指定时间戳转化为指定时区时间戳 |
| 10 | unix_timestamp(string datetime) | bigint | 把string类型的date或日期转化成时间戳Unix |
| 11 | unix_timestamp(timestamp datetime) | bigint | 把string类型的timestamp转化成时间戳Unix |
| 12 | unix_timestamp(string datetime,string pattern) | bigint | 日期按pattern转化成时间戳Unix |
5. 时间计算函数
| 序号 | 函数/方法 | 输出类型 | 说明/样式 |
|---|---|---|---|
| 1 | years_add(timestamp/date date, int/bigint years) | timestamp/date | 增加指定年数 |
| 2 | years_sub(timestamp/date date, int/bigint years) | timestamp/date | 减少指定年数 |
| 3 | months_add(timestamp/date date, int/bigint months) | timestamp/date | 增加指定月数 |
| 4 | months_sub(timestamp/date date, int/bigint months) | timestamp/date | 减少指定月数 |
| 5 | add_months(timestamp/date date, int/bigint months) | timestamp/date | 增加指定月数 |
| 6 | weeks_add(timestamp/date date, int/bigint weeks) | timestamp/date | 增加指定周数 |
| 7 | weeks_sub(timestamp/date date, int/bigint weeks) | timestamp/date | 减少指定周数 |
| 8 | days_add(timestamp/date startdate, int/bigint days) | timestamp/date | 增加指定天数 |
| 9 | days_sub(timestamp/date startdate, int/bigint days) | timestamp/date | 减少指定天数 |
| 10 | date_add(timestamp/date startdate, int/bigint days) | timestamp/date | 增加指定天数 |
| 11 | date_sub(timestamp/date startdate, int/bigint days) | timestamp/date | 减少指定天数 |
| 12 | adddate(timestamp/date startdate, int/int days) | timestamp/date | 增加指定天数 |
| 13 | subdate(timestamp/date startdate,bigint/int days) | timestamp/date | 减少指定天数 |
| 14 | hours_add(timestamp date, int/bigint hours) | timestamp | 增加指定小时 |
| 15 | hours_sub(timestamp date, int/bigint hours) | timestamp | 减少指定小时 |
| 16 | minutes_add(timestamp date, int/bigint minutes) | timestamp | 增加指定分钟 |
| 17 | minutes_sub(timestamp date, int/bigint minutes) | timestamp | 减少指定分钟 |
| 18 | seconds_add(timestamp date, int/bigint seconds) | timestamp | 增加指定秒数 |
| 19 | seconds_sub(timestamp date, int/bigint seconds) | timestamp | 减少指定秒数 |
| 20 | milliseconds_add(timestamp t, int/bigint s) | timestamp | 增加指定毫秒数 |
| 21 | milliseconds_sub(timestamp t, int/bigint s) | timestamp | 减少指定毫秒数 |
| 22 | microseconds_add(timestamp t, int/bigint s) | timestamp | 增加指定微秒数 |
| 23 | microseconds_sub(timestamp t, int/bigint s) | timestamp | 减少指定微秒数 |
| 24 | nanoseconds_add(timestamp t, int/bigint s) | timestamp | 增加指定纳秒数 |
| 25 | nanoseconds_sub(timestamp t, int/bigint s) | timestamp | 减少指定纳秒数 |
| 26 | date_add(timestamp/date startdate, interval_expression) | timestamp/date | 使用参数计算日期增量值(增加) |
| 27 | date_sub(timestamp/date startdate, interval_expression) | timestamp/date | 使用参数计算日期增量值(减少) |
