Hive之函数解析

发布时间 2024-01-08 21:27:25作者: OnePandas

1.1 查看系统自带的函数

-- 查看系统自带函数
show functions;
-- 查看自带函数的用法
desc/describe function 函数名;
-- 查看自带函数的具体用法
desc/describe function extended 函数;

1.2 窗口函数

1.2.1 相关函数说明

函数 说明
over() 指定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而变化。
current row 当前行
n preceding 往前n行数据
n following 往后n行数据
unbounded 起点
unbounded preceding 表示从前面的起点
unbounded following 表示到后面的终点
LAG(col,n,default_val) 往前第n行数据
LEAD(col,n,default_val) 往后第n行数据
ntile(n) 把有序窗口的行分发到指定数据的组中,各个组有编号,编号从1开始,对于每一行,NTILE返回此行所属的组的编号。注意:n必须为int类型。
first_value(col) 只取当前分组的第一个数据
last_value(col) 取当前分组内的最后一行数据,当over中存在排序时,组内每一行数据都是最后一行,可以加范围指定,直接将范围开到最大

范围通过rows between .... and ....指定

1.2.2 数据准备

jack,2017-01-01,10
tony,2017-01-02,15
jack,2017-02-03,23
tony,2017-01-04,29
jack,2017-01-05,46
jack,2017-04-06,42
tony,2017-01-07,50
jack,2017-01-08,55
mart,2017-04-08,62
mart,2017-04-09,68
neil,2017-05-10,12
mart,2017-04-11,75
neil,2017-06-12,80
mart,2017-04-13,94

1.2.3 需求

1、查询在2017年4月份购买过的顾客及总人数

select name,count(*) over() from business where substring(orderdate, 1, 7) ='2017-04' group by name; 

2、查询顾客的购买明细及月购买总额

-- hive语句
select name, orderdate, cost, sum(cost) over(partition by name,month(orderdate)) from business;
-- presto语句
select name, orderdate, cost, sum(cost) over(partition by name,substring(orderdate,1,7)) 
from hive.ceshi.business;

3、上述的场景,将每个顾客的cost按照日期进行累加

-- hive语句
SELECT name,orderdate,cost,
-- 所有行相加
sum(cost) OVER() AS sample1,
-- 按name分组,组内数据相加
sum(cost) OVER(PARTITION BY name) AS sample2,
-- 按name分组,组内数据累加
sum(cost) OVER(PARTITION BY name ORDER BY orderdate) AS sample3,
-- 和sample3一样,由起点到当前行的聚合
sum(cost) OVER(PARTITION BY name ORDER BY orderdate ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS sample4,
-- 当前行和前面一行做聚合
sum(cost) OVER(PARTITION BY name ORDER BY orderdate ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS sample5,
-- 当前行和前边一行及后边一行
sum(cost) OVER(PARTITION BY name ORDER BY orderdate ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS sample6,
-- 当前行及后边所有行
sum(cost) OVER(PARTITION BY name ORDER BY orderdate ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS sample7
FROM ceshi.business;

-- presto语句
select name,orderdate,cost, sum(cost) over(partition by name order by orderdate) as add_sum 
from hive.ceshi.business order by name,orderdate;

rows必须跟在order by 子句之后,对排序的结果进行限制,使用固定的行数来限制分区中的数据行数量

4、查询每个顾客上次的购买时间

-- hive语句
SELECT name, orderdate,lag(orderdate,1) over(PARTITION BY name ORDER BY orderdate) FROM ceshi.business;
-- presto语句
SELECT name, orderdate,lag(orderdate,1) over(PARTITION BY name ORDER BY orderdate) FROM hive.ceshi.business order by name,orderdate;

5、查询前20%时间的订单信息

select name, orderdate, cost
from (select name, orderdate, cost,
             ntile(5) over(order by orderdate) as group_id
      from hive.ceshi.business) as t1
where t1.group_id = 1;

6、创建本地business.txt文件

7、创建hive表并导入数据

-- 创建表
create table business(name string,orderdate string,cost int)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
-- 导入数据
load data local in path "本地文件路径" into table business;

1.3 排序函数

(rank、dense_rank、row_number)

1.3.1 函数说明

RANK() 排序相同时会重复,总数不会变

DENSE_RANK() 排序相同时会重复,总数会减少

ROW_NUMBER() 会根据顺序计算

1.3.2 数据准备

孙悟空,语文,87
孙悟空,数学,95
孙悟空,英语,68
大海,语文,94
大海,数学,56
大海,英语,84
宋宋,语文,64
宋宋,数学,86
宋宋,英语,84
婷婷,语文,65
婷婷,数学,85
婷婷,英语,78

1.3.4 需求

计算每门学科成绩排名

select name,subject,score,
rank() over(partition by subject order by score desc) as rp,
dense_rank() over(partition by subject order by score desc) as drp,
row_number() over(partition by subject order by score desc) as rmp 
from score;

1.3.5 创建本地score.txt

1.3.6 创建hive表

create table ceshi.score(name string,subject string, score int) 
row format delimited fields terminated by ",";
load data local inpath '本地文件路径' into table ceshi.score;

1.4 常用日期函数

sparkSQL要想转时间戳或者其他时间类型需要先设置参数

set spark.sql.legacy.timeParserPolicy=LEGACY;

1、unix_timestamp

unix_timestamp([timeExp[, fmt]]) - Returns the UNIX timestamp of current or specified time.

返回当前或指定时间的时间戳

Arguments:

  • timeExp - A date/timestamp or string. If not provided, this defaults to current time.
  • fmt - Date/time format pattern to follow. Ignored if timeExp is not a string. Default value is "yyyy-MM-dd HH:mm:ss". See Datetime Patterns for valid date and time format patterns.

Examples:

> SELECT unix_timestamp();
 1476884637
> SELECT unix_timestamp('2016-04-08', 'yyyy-MM-dd');
 1460041200

Since: 1.5.0

2、from_unixtime

from_unixtime(unix_time[, fmt]) - Returns unix_time in the specified fmt.

在指定的 fmt 中返回 unix_time

Arguments:

  • unix_time - UNIX Timestamp to be converted to the provided format.
  • fmt - Date/time format pattern to follow. See Datetime Patterns for valid date and time format patterns. The 'yyyy-MM-dd HH:mm:ss' pattern is used if omitted.

Examples:

SELECT from_unixtime(0, 'yyyy-MM-dd HH:mm:ss');
SELECT from_unixtime(1603843200, 'yyyy-MM-dd HH:mm:ss');
-- 1969-12-31 16:00:00

SELECT from_unixtime(0);
-- 1969-12-31 16:00:00

Since: 1.5.0

将时间戳转为日期格式

select from_unixtime(1603843200);
-- 后边可以增加要转换成的时间类型
SELECT from_unixtime(1603843200, 'yyyy-MM-dd HH:mm:ss');

3、current_date

当前返回当前年月日

select current_date;
-- 输出

4、current_timestamp

当前的日期加时间

select current_timestamp;

5、to_date

抽取日期部分

select to_date('2020-10-28 12:12:12');

6、year

获取年

select year('2020-10-28 12:12:12');

7、month

获取月

select month('2020-10-28 12:12:12');

8、day

获取日

select day('2020-10-28 12:12:12');

9、hour

获取小时

select hour('2020-10-28 12:12:12');

10、minute

获取分

select minute('2020-10-28 12:12:12');

11、second

获取秒

select second('2020-10-28 12:12:12');

12、weekofyear

当前时间是一年中的第几周

select weekofyear('2020-10-28 12:12:12');

13、dayofmonth

返回今天是当前月的第几天

select dayofmonth('2020-10-28 12:12:12');

14、months_between

两个日期间的月份

select months_between('2020-04-01','2020-10-28');

15、add_months

日期加减月

select add_months('2020-10-28',-3);

16、datediff

两个日期相差的天数

select datediff('2020-11-04','2020-10-28');

17、date_add

日期加天数

select date_add('2020-10-28',4);

18、date_sub

日期减天数

select date_sub('2020-10-28',-4);

19、last_day

日期的当月的最后一天

select last_day('2020-02-30');

20、date_format

格式化日期

select date_format('2020-10-28 12:12:12','yyyy/MM/dd HH:mm:ss');

21、next_day

-- 周指标相关,获取str下周一日期
next_day(to_date(str),'MO')

22、trunc

-- 返回日期最开始年份或月份。string1可为年(YYYY/YY/YEAR)或月 (MONTH/MON/MM)。
select trunc('2019-03-06','MM');
输出:'2019-03-01'
select trunc('2019-03-06','YYYY');
输出:'2019-01-01' 

23、日期之间切换

思想:先转换成时间戳,再由时间戳转换为对应格式。
--20171205转成2017-12-05 
select from_unixtime(unix_timestamp('20171205','yyyymmdd'),'yyyy-mm-dd') from dual;

--2017-12-05转成20171205
select from_unixtime(unix_timestamp('2017-12-05','yyyy-mm-dd'),'yyyymmdd') from dual;

24、取最近30天数据

datediff(CURRENT_TIMESTAMP ,gmt_create)<=30 

25、两个日期相差多少小时

select (unix_timestamp('2018-05-25 12:03:55') - unix_timestamp('2018-05-25 11:03:55'))/3600
-- 输出:1

26、两个日期相差多少分钟

select (unix_timestamp('2018-05-25 12:03:55') - unix_timestamp('2018-05-25 11:03:55'))/60

-- 输出:60

27、计算某天属于星期几

SELECT IF(pmod(datediff('2018-05-20', '1920-01-01') - 3, 7)='0', 7, pmod(datediff('2018-05-20', '1920-01-01') - 3, 7)) 
-- 输出:7

28、add_month

SELECT add_months('2016-08-31', 1);
-- 2016-09-30

29、dayofweek

-- 0对应的是周日,以此类推
SELECT dayofweek('2009-07-04');
-- 输出:7

30、dayofyear

返回今天是本年的第几天

SELECT dayofyear('2022-05-20');
-- 输出:140

31、make_date

以年、月、日字段创建日期

SELECT make_date(2013, 7, 15);
-- 输出:2013-07-15

32、now

spark的用法

返回当前年月日时分秒

select now();
-- 输出:2022-05-27 18:32:54.798000000

1.5 常用数学函数

1、round/bround/format_number

四舍五入

select round(1234.5678, 2);
-- 输出:1234.57
select bround(1234.5678, 2);
-- 输出:1234.57
select format_number(1234.5678, 2);
-- 输出:1,234.57
select format_number(1234.5678, '######.##');
-- 输出:1234.57

2、ceil/ceiling

向上取整

select ceil(3.14);
select ceil(3.54);

3、floor

向下取整

select floor(3.14);
select floor(3.54);

4、rand

排序函数

-- 取随机数函数 : rand
-- 语法: rand(),rand(int seed)
-- 返回值: double
-- 说明: 返回一个0到1范围内的随机数。如果指定种子seed,则会等到一个稳定的随机数序列
select rand(); 
-- 输出:0.5577432776034763

5、abs

绝对值函数

-- 绝对值函数 : abs
-- 语法: abs(double a) abs(int a)
-- 返回值: double int
-- 说明: 返回数值a的绝对值
select abs(‐3.9) from dual; 
-- 输出:3.9
select abs(10.9); 
-- 输出:10.9

6、pmod

-- (pmod(int a, int b))返回a除b的余数的绝对值。
select datediff('2018-01-02','2018-01-01')   
-- 输出:1
select pmod(datediff('2018-01-02','2018-01-01') + 1,7) 
-- 输出2

7、pow

幂运算函数

-- 语法: pow(double a, double p)
-- 返回值: double
-- 说明: 返回a的p次幂
select pow(2,4) ;
-- 16.0

8、sqrt

开平方根函数

-- 语法: sqrt(double a)
-- 返回值: double
-- 说明: 返回a的平方根
select sqrt(16) ;
-- 4.0

9、log10

对数函数

-- 语法: log10(double a)
-- 返回值: double
-- 说明: 返回以10为底的a的对数
select log10(100) ;
-- 2.0

10、exp

自然指数函数

-- 语法: exp(double a)
-- 返回值: double
-- 说明: 返回自然对数e的a次方
select exp(2) ;
-- 7.38905609893065

12、cbrt

返回传入参数的立方根

select cbrt(8);
-- 输出:2

13、greatest

返回传入参数的最大值

SELECT greatest(10, 9, 2, 4, 3);
-- 输出:10

14、hypot

传入两个参数,返回多个参数的乘方之和的开方

select hypot(3,4);
-- 输出:5
-- 等价于
select sqrt(3*3+4*4);

14、least

返回传入参数的最小值

SELECT least(10, 9, 2, 4, 3);
-- 输出:2

15、avg/mean

求平均值

SELECT avg(col) FROM VALUES (1), (2), (3) AS tab(col);
-- 输出:2.0
SELECT mean(col) FROM VALUES (1), (2), (3) AS tab(col);
-- 输出:2.0

16、mod/%

取余数

SELECT MOD(2, 1.8);
-- 输出:0.2
SELECT 2 % 1.8;
-- 输出:0.2

17、log

取对数

SELECT log(10, 100);
-- 输出:2.0

18、sum

求和


1.6 常用字符串函数

1、upper/ucase

转大写

select upper('low');
select ucase('low');

2、lower/lcase

转小写

select lower('LOW');
select lcase('LOW');

3、length

返回字符串长度

select length("atguigu");

4、trim

前后去空格

select trim(" atguigu ");

5、lpad

向左补齐,到指定长度

select lpad('atguigu',9,'g');

6、rpad

向右补齐,到指定长度

select rpad('atguigu',9,'g');

8、split

-- 将字符串转化为数组,即:split('a,b,c,d' , ',') ==> ["a","b","c","d"]
select split("hadoop_spark_hive","_");
-- 输出: ["hadoop","spark","hive"]

10、reverse

返回字符串的反转结果

select reverse('abcd');
-- 输出: dcba

11、concat

将字符串拼接起来

select concat(strA, strB);
-- 输出: strAstrB

12、concat_ws

字符串拼接第一个字符为拼接符号,其余为要拼接的内容

select concat_ws(",","strA","strB");
-- 输出: strA,strB

13、substr/substring

按照给定的数字截取字符串一定长度内容

substr/substring
select substr('abcde',2);从第二个截,截到结尾
-- 输出: bcde
select substr('abcde',1,3);从第一个截,截三个长度
-- 输出: abc
select substr('wfeww',-2);从尾部截,截两个长度
-- 输出: tr

14、repeat

返回重复n次后的str字符串repeat(string str, int n)

select repeat('abc',5);
-- 输出: abcabcabcabcabc

15、ltrim

去除左侧空格

select ltrim(" AAA");
-- 输出: AAA

16、rtrim

去除右侧空格

select rtrim("AAA ");
-- 输出: AAA

18、parse_url

-- 语法: parse_url(string urlString, string partToExtract [, string keyToExtract])
-- 返回值: string
-- 说明:返回URL中指定的部分。partToExtract的有效值为:HOST, PATH, QUERY, REF, PROTOCOL, AUTHORITY, FILE, and USERINFO.
select parse_url('https://www.tableName.com/path1/p.php?k1=v1&k2=v2#Ref1', 'HOST') from tableName;
-- 输出:www.tableName.com 
select parse_url('https://www.tableName.com/path1/p.php?k1=v1&k2=v2#Ref1', 'QUERY', 'k1') from tableName;
-- 输出:v1

23、instr

返回字符串中某个元素的下标

-- 如果字符元素存在返回对应的下标,不存在返回0
select instr('Li jian','f');
-- 输出:0

24、initcap

将每个字母的首字母转换为大写,其他为小写

select initcap("LI JIAN IS BOY");
-- 输出:Li Jian Is Boy

25、left

获取传入参数左侧n位元素

SELECT left('Spark SQL', 3);
-- 输出:Spa

27、right

获取传入参数右侧n位元素

SELECT right('Spark SQL', 3);
-- 输出:SQL

28、locate

返回给定元素所在的下标

SELECT locate('bar', 'foobarbar');
-- 输出:4
SELECT locate('bar', 'foobarbar', 5);
-- 输出:7
SELECT POSITION('bar' IN 'foobarbar');
-- 输出:4

1.7 数组/集合操作

1、size

集合中元素的个数

select size(friends) from test3;

4、array_contains

判断array中是否包含某个元素

select array_contains(friends,'bingbing') from test3;

5、sort_array

将array中的元素排序

select sort_array(friends) from test3;

6、grouping_set(spark)

多维分析

7、flatten(spark)

将多个数组合并为一个数组

select flatten(array(`array`('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T','U', 'V', 'W', 'X', 'Y', 'Z'),`array`(269, 732, 677, 877, 953, 396, 268, 92, 173, 202, 682, 418, 411, 884, 337, 91, 153, 764, 546, 748,696, 398, 518, 806, 173, 716, 929, 935, 666,105),`array`('a','b','c')));
-- 输出:["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","269","732","677","877","953","396","268","92","173","202","682","418","411","884","337","91","153","764","546","748","696","398","518","806","173","716","929","935","666","105","a","b","c"]                      

8、filter(spark)

spark的函数

返回数组中符合条件的元素

select filter(`array`('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T','U', 'V', 'W', 'X', 'Y', 'Z'), x -> x < 'F');
-- 输出:["A","B","C","D","E"]
select filter(`array`(269, 732, 677, 877, 953, 396, 268, 92, 173, 202, 682, 418, 411, 884, 337, 91, 153, 764, 546, 748,696, 398, 518, 806, 173, 716, 929, 935, 666, 105), x -> x % 2 != 0);
-- 输出:[269,677,877,953,173,411,337,91,153,173,929,935,105]

9、element_at(spark)

spark函数

-- 根据下标获取数组或者map的元素值
select element_at(`array`('a','b','c','d','e','f'),2);
-- 输出:b
select element_at(`map`('a',1, 'b',2),'b');
-- 输出:2

10、array_union(spark)

spark函数

将两个数组拼接起来,并去重

select array_union(`array`(1,2,3,4,5),`array`(3,4,5,6,7,8)) as au;
-- 输出:[1,2,3,4,5,6,7,8]

11、arrays_overlap(spark)

spark函数

如果两个数组有交集返回true,没有交集返回false,两个数组都为null返回null

select arrays_overlap(`array`(1,2,3,4,5),`array`(3,4,5,6,7,8)) as ao;
-- 输出:true

12、array_repeat(spark)

spark函数

将元素复制多份并形成一个数组

select array_repeat(5,3) as ar;
-- 输出:[5,5,5]
select array_repeat("张三",3) as ar;
-- 输出:["张三","张三","张三"]

13、array_remove(spark)

spark函数

从数组中移除指定的元素

select array_remove(`array`(1,2,3,3,null,4,null,5),3) as ar;
-- 输出:[1,2,null,4,null,5]

14、array_distinct(spark)

spark函数

去除数组中的重复元素

select array_distinct(`array`(1,2,3,4,5,6,7,8,9,9,8,7,6,6,5,4,3,2,1)) as ad;
-- 输出:[1,2,3,4,5,6,7,8,9]

15、array_except(spark)

spark函数

显示集合1对于集合2的差集,也就是显示集合1独有的部分

select array_except(`array`(1,2,3,4,5),`array`(3,4,5,6,7,8)) as ae;
-- 输出:[1,2]

16、array_intersect(spark)

spark函数

显示集合1和集合2的并集,也就是集合1和集合2都有的部分

select array_intersect(`array`(1,2,3,3,4,5),`array`(3,3,4,4,5,6,7,8)) as ae;
-- 输出:[3,4,5]

17、array_join(spark)

spark函数

将集合内的元素用指定的字符拼接在一起,如果想要替换null值,在拼接字符后在增加一个替换元素

select array_join(`array`(1,2,3,3,null,4,null,5),'|+|') as aj;
-- 输出:1|+|2|+|3|+|3|+|4|+|5
select array_join(`array`(1,2,3,3,null,4,null,5),'|+|','kong') as aj;

18、array_max/array_min(spark)

spark函数

获取数组中的最大值/最小值

select array_max(`array`(1,2,3,3,null,4,null,5)) as am;
-- 输出:5
select array_min(`array`(1,2,3,3,null,4,null,5)) as am;
-- 输出:1

19、array_position(spark)

spark函数

返回数组中给定元素的下标,不存在返回0

select array_position(`array`(1,2,3,3,null,4,null,5),5) as ap;
-- 输出:8

20、array_sort(spark)

spark函数

对输入的数组进行排序,默认是升序

select array_sort(`array`(1,2,3,3,4,5,9,8,7,6)) as `as` ;
-- 输出:[1,2,3,3,4,5,6,7,8,9]
-- 想要降序排列
select array_sort(`array`(1,2,3,3,4,5,9,8,7,6), (left, right) ->
    case
    when left is null and right is null then 0
    when left is null then -1
    when right is null then 1
    when left < right then 1
    when left > right then -1
    else 0
    end) as `as`;
-- 或者使用reverse函数
select reverse(array_sort(`array`(1,2,3,3,4,5,9,8,7,6))) as `as`;

21、collect_list

列出传入字段的所有内容形成一个数组,不去重

-- 列出该字段所有的值,不去重
select collect_list(id) as id from tb;
-- 如果获取的是一个集合可以通过下标的方式获取对应值
select collect_list(id)[0] as id from tb;

22、collect_set

-- 列出某个字段所有的内容,会去重
select collect_set(id) as id from tb;
-- 如果获取的是一个集合可以通过下标的方式获取对应值
select collect_set(id)[0] as id from tb;

23、json_array_length(spark)

spark函数

返回最外层数组长度

SELECT json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]');
-- 输出:5

24、find_in_set

集合查找函数

select find_in_set('ab','ef,ab,de');
-- 输出:2
select find_in_set('at','ef,ab,de');
-- 输出:0

1.8 排序函数

1、order by

会对输入做全局排序,因此只有一个reducer(多个reducer无法保证全局有序)。只有一个reducer,会导致当输入规模较大时,需要较长的计算时间

-- 字段升序或者降序排列
select * from table order by 字段 asc/desc;

2、sort by

不是全局排序,其在数据进入reducer前完成排序


3、distribute by

按照指定的字段对数据进行划分输出到不同的reduce中


4、cluster by

除了具有distribute by 的功能外还兼具sort by 的功能。

1.9 条件函数

1、case when then else end

-- 第一种写法
select  dept_id,
		sum(case sex when '男' then 1 else 0 end) as male_count,
		sum(case sex when '女' then 1 else 0 end) as female_count
from emp_sex
group by dept_id;
-- 第二种写法
select case when 1=2 then 'tom' when 2=2 then 'mary' else 'tim' end from tableName;

2、if

select  dept_id,
		sum(if(sex='男',1,0)) as male_count,
		sum(if(sex='女',1,0)) as female_count
from emp_sex
group by dept_id;

3、coalesce

-- 遇到非null值即停止并返回该值。如果所有的表达式都是空值,最终将返回一个空值。
select coalesce(a,b,c,...);

4、isnull

-- 若a为null则返回true,否则返回false
select isnull(a)

5、isnotnull

-- 如果不为 null,则返回 true,否则返回 false。
SELECT isnotnull(1);
-- true

6、nvl

给值为NULL的数据赋值,它的格式是NVL(value, default_value) 。它的功能是如果value为NULL, 则NVL函数返回default_value的值, 否则返回value的值, 如果两个参数散都为NULL, 则返回NULL

select 字段1, nvl(字段1,字段2/默认值) from 表名;

7、count_if(spark)

如果满足条件就计数

count_if(expr) - Returns the number of TRUE values for the expression.

返回提供的表达式唯一且非空的行数。

Examples:

> SELECT count_if(col % 2 = 0) FROM VALUES (NULL), (0), (1), (2), (3) AS tab(col);
 2
> SELECT count_if(col IS NULL) FROM VALUES (NULL), (0), (1), (2), (3) AS tab(col);
 1

Since: 3.0.0

8、every(spark)

如果传入参数都为true,则返回true,否则返回false

select every(col1) from values (true),(true),(true) as tab(col1);
-- 输出:true

9、any(spark)

如果有一个值为真则返回真,否则返回假

SELECT any(col) FROM VALUES (true), (false), (false) AS tab(col);
-- 输出:false

10、ifnull(spark)

如果第一个参数为null,则返回第二个参数

SELECT ifnull(NULL, array('2'));
-- 输出:["2"]

1.10 运算符

1、算数运算符

A+B A和B相加
A-B A减去B
A*B A和B相乘
A/B A除以B
A%B A对B取余
A&B A和B按位取与
A|B A和B按位取或
A^B A和B按位取异或
~A A按位取反

2、比较运算符

操作符 支持的数据类型 描述
A=B 基本数据类型 如果A等于B则返回TRUE,反之返回FALSE
A<=B 基本数据类型 如果A和B都为NULL,则返回TRUE,如果一边为NULL,返回False
A 基本数据类型 A或者B为NULL则返回NULL;如果A不等于,则返回TRUE,反之返回FALSE
A 基本数据类型 A或者B为NULL,则返回NULL;如果 A小于B,则返回TRUE,反之返回FALSE
A<=B 基本数据类型 A或者B为NULL,则返回NULL;如果A小于等于B,则返回TRUE,反之返回FALSE
AB 基本数据类型 A或者B为NULL,则返回NULL;如果A大于B,则返回TRUE,反之返回FALSE
A=B 基本数据类型 A或者B为NULL,则返回NULL;如果A大于等于B,则返回TRUE,反之返回FALSE
A [NOT] BETWEEN B AND C 基本数据类型 如果A,B或者C任一为NULL,则结果为NULL。如果A的值大于等于B而且小于或等于C,则结果为TRUE,反之为FALSE。如果使用NOT关键字则可达到相反的效果。
A IS NULL 所有数据类型 如果A等于NULL,则返回TRUE,反之返回FALSE
A IS NOT NULL 所有数据类型 如果A不等于NULL,则返回TRUE,反之返回FALSE
IN(数值1,数值2,..) 所有数据类型 使用N运算显示列表中的值
A [NOT] LIKE B string 类型 B是一个SQL下的简单正则表达式,也叫通配符模式,如果A与其匹配的话,则返回TRUE;反之返回FALSE, B的表达式说明如下: x%,表示A必须以字母'x'开头, '%x'表示A 必须以字母,x,结尾,而"%x%,表示A包含有字母, x' ,可以位于开头,结尾或者字符串中间。如果使用NOT关键字则可达到相反的效果。
A RLIKE B,AREGEXP B string 类型 B是基于java的正则表达式,如果A与其匹配,则返回TRUE;反之返回FALSE。匹配使用的是JDK中的正则表达式接口实现的,因为正则也依据其中的规则。例如,正则表达式必须和整个字符串A相匹配,而不是只需与其字符串匹配。

3、逻辑运算符

操作符 含义
AND 逻辑并
OR 逻辑或
NOT 逻辑否

1.11 类型转换

1、cast

将数据转换成指定的数据类型

select cast('1' as DOUBLE); 
-- 输出:1.0

2、ascii

转换成asc码

select ascii('b');
-- 输出:98

3、bin

转换成二进制

select bin(123123) as II 
-- 输出:11110000011110011

十六进制函数: hex()、将十六进制转化为字符串函数: unhex() 进制转换函数: conv(bigint num, int from_base, int to_base) 说明: 将数值num从from_base进制转化到to_base进制

此外还有很多数学函数:绝对值函数: abs()、正取余函数: pmod()、正弦函数: sin()、反正弦函数: asin()、余弦函数: cos()、反余弦函数: acos()、positive函数: positive()、negative函数: negative()

4、hex

转换为16进制

SELECT hex('Spark SQL');
-- 输出:537061726B2053514C

5、hash

返回传入参数的哈希值

SELECT hash('Spark', array(123), 2);
-- 输出:-1321691492

6、int(spark)

将数据转换为int类型

select `int`("12.34");
-- 输出:12

7、md5

返回MD5 128位校验码

SELECT md5('Spark');
-- 输出:8cde774d6f7333752ed72cacddb05126

1.12 数据类型

1、TINYINT

byte类型 1 byte有符号整数

2、SMALINT

short类型 2 byte有符号整数

3、INT

int类型 4 byte有符号整数

4、BIGINT

long类型 8 byte有符号整数

5、BOOLEAN

boolean类型 布尔类型,true或者false

6、FLOAT

float类型 单精度浮点数

7、DOUBLE

double类型 双精度浮点数

8、STRING

string类型 字符系列

9、TIMESTAMP

时间戳,纳秒精度

10、BINARY

字节数组

11、decimal

任意精度的带符号小数

12、varchar

可变字符串

13、char

固定长度字符串

14、date

日期

1.13 其他函数

1、limit

-- 分页展示
SELECT * FROM customers ORDER BY create_date LIMIT 2, 5;
-- 每页有5个,展示第三页的内容求m的值,公式为m=(3-1)*n  limit m,n

2、like

使用LIKE运算选择类似的值
选择条件可以包含字符或数字
%/*:代表零个或多个字符(任意个字符)
_:代表一个字符

-- 查找名字以A开头的信息
 select * from 表名 where 字段 LIKE 'A*';
-- 查找名字中第二个字母为A的信息
 select * from 表名 where 字段 LIKE '_A*';

3、rlike

RLIKE子句是Hive中这个功能的一个扩展,其可以通过Java的正则表达式这个更强大的语言来指定匹配条件

-- 查找名字中带有A的信息
select * from 表名 where 字段 RLIKE '[A]';

4、partitioned by

-- 指定分区字段,并指定存储格式
CREATE TRANSACTIONAL TABLE transactional_table_test(key string, value string) PARTITIONED BY(dt string) STORED AS ORC;

5、percentile

-- 语法: percentile(BIGINT col, p)
-- 返回值: double
-- 说明: 求准确的第pth个百分位数,p必须介于0和1之间,但是col字段目前只支持整数,不支持浮点数类型
-- 求单个分位数
SELECT percentile(col, 0.3) FROM VALUES (0), (10) AS tab(col);
-- 求多个分位数
SELECT percentile(col, array(0.25, 0.75)) FROM VALUES (0), (10) AS tab(col);

6、inline/inline_out

将结构数据分解为表

SELECT inline(array(struct(1, 'a'), struct(2, 'b')));
 1  a
 2  b

1.14 字典

1、json_object_keys(spark)

以数组的形式返回所有的键

SELECT json_object_keys('{"f1":"abc","f2":{"f3":"a", "f4":"b"}}');
-- 输出:["f1","f2"]

2、map_concat(spark)

返回两个字典的并集

SELECT map_concat(map(1, 'a', 2, 'b'), map(3, 'c'));
-- 输出:{1:"a",2:"b",3:"c"}

3、map_entries(spark)

将字典拆解成单独的字典元素

SELECT map_entries(map(1, 'a', 2, 'b'));
-- 输出:[{"key":1,"value":"a"},{"key":2,"value":"b"}]

4、map_filter(spark)

使用函数过滤掉字典中不符合条件的元素

SELECT map_filter(map(1, 0, 2, 2, 3, -1), (k, v) -> k > v);
-- 输出:{1:0,3:-1}

5、map_from_arrays(spark)

将两个数组映射为字典,元素不能为空

SELECT map_from_arrays(array(1.0, 3.0), array('2', '4'));
-- 输出:{1.0:"2",3.0:"4"}

6、map_keys

以数组的形式返回字典的keys

SELECT map_keys(map(1, 'a', 2, 'b'));
-- 输出:[1,2]

7、map_values

以数组的形式返回字典的所有values

SELECT map_values(map(1, 'a', 2, 'b'));
-- 输出:["a","b"]

8、map_zip_with(spark)

SELECT map_zip_with(map(1, 'a', 2, 'b'), map(1, 'x', 2, 'y'), (k, v1, v2) -> concat(v1, v2));
-- 输出:{1:"ax",2:"by"}

9、named_struct

已给定的字符组成字典

SELECT named_struct("a", 1, "b", 2, "c", 3);
-- 输出:{"a":1,"b":2,"c":3}

10、to_json(spark)

将数组转换为字典

> SELECT to_json(named_struct('a', 1, 'b', 2));
 {"a":1,"b":2}
> SELECT to_json(named_struct('time', to_timestamp('2015-08-26', 'yyyy-MM-dd')), map('timestampFormat', 'dd/MM/yyyy'));
 {"time":"26/08/2015"}
> SELECT to_json(array(named_struct('a', 1, 'b', 2)));
 [{"a":1,"b":2}]
> SELECT to_json(map('a', named_struct('b', 1)));
 {"a":{"b":1}}
> SELECT to_json(map(named_struct('a', 1),named_struct('b', 2)));
 {"[1]":{"b":2}}
> SELECT to_json(map('a', 1));
 {"a":1}
> SELECT to_json(array((map('a', 1))));
 [{"a":1}]
 
 select map_from_arrays(collect_list(M),collect_list(A)) from study_one_day.t20220607_1 group by Y;

11、map_from_arrays(spark)

将两个数组转换为字典

select map_from_arrays(collect_list(M),collect_list(A)) from study_one_day.t20220607_1 group by Y;

12、get_json_object

根据字典的键获取字典的值

SELECT get_json_object('{"a":"b"}', '$.a');
-- 输出:b
-- 语法: get_json_object(string json_string, string path)
-- 返回值: string
-- 说明:解析json的字符串json_string,返回path指定的内容。如果输入的json字符串无效,那么返回NULL。
select  get_json_object('{"store":{"fruit":\[{"weight":8,"type":"apple"},{"weight":9,"type":"pear"}], "bicycle":{"price":19.95,"color":"red"} },"email":"amy@only_for_json_udf_test.net","owner":"amy"}','$.owner') from tableName;
-- ------------------------------------------------------------------------------------------------------------
select id,
       get_json_object(t.js, '$.name') as name,
       get_json_object(t.js, '$.age')  as age
from test02 as t;

13、json_tuple

批量获取json字段的内容

select t1.id,t2.* from  test02 as t1 lateral view json_tuple(t1.js, 'name','age') t2 as name,age;

1.15 正则

字符 描述
\ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如,'n' 匹配字符 "n"。'\n' 匹配一个换行符。序列 '\' 匹配 "" 而 "(" 则匹配 "("。
^ 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 '\n' 或 '\r' 之后的位置。
$ 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 '\n' 或 '\r' 之前的位置。
* 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。
+ 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
? 匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 。? 等价于 {0,1}。
n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。
n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。
m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。
? 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 "oooo",'o+?' 将匹配单个 "o",而 'o+' 将匹配所有 'o'。
. 匹配除换行符(\n、\r)之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用像"(.|\n)"的模式。
(pattern) 匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 $0…$9 属性。要匹配圆括号字符,请使用 '(' 或 ')'。
(?:pattern) 匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用。例如, 'industr(?:y|ies) 就是一个比 'industry|industries' 更简略的表达式。
(?=pattern) 正向肯定预查(look ahead positive assert),在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,"Windows(?=95|98|NT|2000)"能匹配"Windows2000"中的"Windows",但不能匹配"Windows3.1"中的"Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern) 正向否定预查(negative assert),在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如"Windows(?!95|98|NT|2000)"能匹配"Windows3.1"中的"Windows",但不能匹配"Windows2000"中的"Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?<=pattern) 反向(look behind)肯定预查,与正向肯定预查类似,只是方向相反。例如,"`(?<=95
(?<!pattern) 反向否定预查,与正向否定预查类似,只是方向相反。例如"`(?<!95
x|y 匹配 x 或 y。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。
[xyz] 字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。
[^xyz] 负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'、'l'、'i'、'n'。
[a-z] 字符范围。匹配指定范围内的任意字符。例如,'[a-z]' 可以匹配 'a' 到 'z' 范围内的任意小写字母字符。
[^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。例如,'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范围内的任意字符。
\b 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\cx 匹配由 x 指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。
\d 匹配一个数字字符。等价于 [0-9]。
\D 匹配一个非数字字符。等价于 [^0-9]。
\f 匹配一个换页符。等价于 \x0c 和 \cL。
\n 匹配一个换行符。等价于 \x0a 和 \cJ。
\r 匹配一个回车符。等价于 \x0d 和 \cM。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\t 匹配一个制表符。等价于 \x09 和 \cI。
\v 匹配一个垂直制表符。等价于 \x0b 和 \cK。
\w 匹配字母、数字、下划线。等价于'[A-Za-z0-9_]'。
\W 匹配非字母、数字、下划线。等价于 '[^A-Za-z0-9_]'。
\xn 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,'\x41' 匹配 "A"。'\x041' 则等价于 '\x04' & "1"。正则表达式中可以使用 ASCII 编码。
\num 匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,'(.)\1' 匹配两个连续的相同字符。
\n 标识一个八进制转义值或一个向后引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为向后引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。
\nm 标识一个八进制转义值或一个向后引用。如果 \nm 之前至少有 nm 个获得子表达式,则 nm 为向后引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足,若 n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm。
\nml 如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。
\un 匹配 n,其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如, \u00A9 匹配版权符号 (?)。

1、regexp_replace

使用正则表达式匹配目标字符串,匹配成功后替换!

SELECT regexp_replace('2020/10/25', '/', '-');
-- 输出:2020-10-25

2、regexp_extract

正则表达式解析函数

-- 语法: regexp_extract(string subject, string pattern, int index)
-- 返回值: string
-- 说明:将字符串subject按照pattern正则表达式的规则拆分,返回index指定的字符。
select regexp_extract('foothebar', 'foo(.*?)(bar)', 1) from tableName;
-- 输出:the
select regexp_extract('foothebar', 'foo(.*?)(bar)', 2) from tableName;
-- 输出:bar
select regexp_extract('foothebar', 'foo(.*?)(bar)', 0) from tableName;
-- 输出:foothebar
-- strong>注意,在有些情况下要使用转义字符,下面的等号要用双竖线转义,这是java正则表达式的规则。
select data_field,
	regexp_extract(data_field,'.*?bgStart\\=([^&]+)',1) as aaa,
	regexp_extract(data_field,'.*?contentLoaded_headStart\\=([^&]+)',1) as bbb,
	regexp_extract(data_field,'.*?AppLoad2Req\\=([^&]+)',1) as ccc 
from pt_nginx_loginlog_st 
where pt = '2021-03-28' limit 2;

3、rlike

一般用于筛选符合条件

select count(1) from sou_gou.user_find where user_id rlike '^[0-9]+$';
-- 统计user_id都是数字组成的

4、regexp_extract_all(spark)

SELECT regexp_extract_all('100-200, 300-400', '(\\d+)-(\\d+)', 1);
-- 输出:["100","300"]

5、regexp_like(spark)

SELECT regexp_like('%SystemDrive%\\Users\\John', '%SystemDrive%\\\\Users.*');
-- 输出:true

6、regexp

SELECT regexp('%SystemDrive%\\Users\\John', '%SystemDrive%\\\\Users.*');
-- 输出:true

1.16 常用聚合函数

1 求总行数

select count(1) as cnt from 表名;

2 求最大值

select max(字段) as max_value from 表名;

3 求最小值

select min(字段) as min_value from 表名;

4 求和

select sum(字段) as sum_value from 表名;

5 求平均值

select avg(字段) as avg_value from 表名;

1.19 数据类型

分类 类型 描述 字面量示例
原始类型 BOOLEAN true/false TRUE
原始类型 TINYINT 1字节的有符号整数 -128~127 1Y
原始类型 SMALLINT 2个字节的有符号整数,-32768~32767 1S
原始类型 INT 4个字节的带符号整数 1
原始类型 BIGINT 8字节带符号整数 1L
原始类型 FLOAT 4字节单精度浮点数1.0
原始类型 DOUBLE 8字节双精度浮点数 1.0
原始类型 DEICIMAL 任意精度的带符号小数 1.0
原始类型 STRING 字符串,变长 "a","b"
原始类型 VARCHAR 变长字符串 "a","b"
原始类型 CHAR 固定长度字符串 "a","b"
原始类型 BINARY 字节数组 无法表示
原始类型 TIMESTAMP 时间戳,毫秒值精度 122327493795
原始类型 DATE 日期 '2016-03-29'
原始类型 INTERVAL 时间频率间隔
复杂类型 ARRAY 有序的的同类型的集合 array(1,2)
复杂类型 MAP key-value,key必须为原始类型,value可以任意类型 map('a',1,'b',2)
复杂类型 STRUCT 字段集合,类型可以不同 struct(‘1’,1,1.0), named_stract(‘col1’,’1’,’col2’,1,’clo3’,1.0)
复杂类型 UNION 在有限取值范围内的一个值 create_union(1,’a’,63)

对decimal类型简单解释下: 用法:decimal(11,2) 代表最多有11位数字,其中后2位是小数,整数部分是9位;如果整数部分超过9位,则这个字段就会变成null;如果小数部分不足2位,则后面用0补齐两位,如果小数部分超过两位,则超出部分四舍五入 也可直接写 decimal,后面不指定位数,默认是 decimal(10,0) 整数10位,没有小数