当前位置: 首页 > news >正文

hive SQL查询与函数

1. 查询语法

SELECT [ALL | DISTINCT] select_expr, select_expr, ... 

FROM table_reference

[WHERE where_condition]

[GROUP BY col_list]

[HAVING col_list]

[ORDER BY col_list]

[CLUSTER BY col_list

        | [DISTRIBUTE BY col_list] [SORT BY col_list]

]

[LIMIT [offset,] rows]

Hive中查询语法与MySQL中类似,关于以上建表语法解释如下:

  • SELECT: SELECT 语句可以是union查询中的一部分,也可以是某个查询的子查询。
  • ALL|DISTINCT:返回所有行或者去重后的行。支持 select distinct * 查询。
  • FROM table_reference:表示查询的输入,可以是普通表、视图或者子查询。
  • WHERE:查询条件,支持部分类型的子查询。
  • GROUP BY :分组查询,指定分组列。
  • HAVING:分组后对聚合结果过滤。
  • ORDER BY|CLUSTER BY|DISTRIBUTE BY|SORT BY:排序相关操作。
  • LIMIT:限制SELECT 语句返回的行数,接受一个或两个数字参数,它们都必须是非负整数常量。第一个参数指定要返回的第一行的偏移量,第二个参数指定要返回的最大行数。当给出单个参数时,它代表最大行数并且偏移量默认为 0。

注意:

1. 查询Hive表数据时,表和列名不区分大小写。

2. 使用Beeline或者DataGrip连接操作Hive时,后续可以使用Hive本地模式,可以通过“hive.exec.mode.local.auto”参数来开启,这样Hive查询就可以直接在HiveServer2本机执行,而不在集群上运行,在一些测试SQL场景中非常实用。

Hive启动后,默认使用JVM内存为256M,后续如果使用Hive本地模式运行SQL时,该内存较小会导致本地模式报错,最好将使用内存调大,可以通过HiveServer2节点上的$HIVE_HOME/conf/hive-env.sh文件中“HADOOP_HEAPSIZE”属性配置Hive使用内存:

#配置hive-env.sh HADOOP_HEAPSIZE参数

export HADOOP_HEAPSIZE=2048

2. groupby

Group By语句需要和聚合函数一起使用,表示按照组统计聚合,聚合操作包括COUNT/SUM/MIN/MAX/AVG/COUNT(DISTINCT...),select语句只能包含group by子句包含的列。

2.1 测试数据

#准备如下文件数据 data.txt 

1,张三,男,25,手机,3000.00,2025-01-01 

2,李四,女,30,电脑,7000.00,2025-01-01 

3,王五,男,22,耳机,500.00,2025-01-02 

4,赵六,女,28,手机,3200.00,2025-01-03 

5,孙七,男,25,键盘,200.00,2025-01-03 

6,周八,女,30,手机,3100.00,2025-01-04 

7,吴九,男,25,鼠标,150.00,2025-01-04 

8,郑十,女,30,鼠标,1200.00,2025-01-05


#创建 user_order表,并加载数据 

CREATE TABLE user_order(

        userid INT, 

        name STRING,

        gender STRING,

        age INT,

        product STRING,

        amount DOUBLE,

        purchase_date STRING

ROW FORMAT DELIMITED FIELDS TERMINATED BY ','; 

load data inpath '/data.txt' into table user_order;

2.2 普通测试

set hive.exec.mode.local.auto=true;#按照性别统计用户数 SELECT gender, COUNT(*) AS cnt FROM user_order GROUP BY gender;
+---------+------+
| gender  | cnt  |
+---------+------+
| 女       | 4    |
| 男       | 4    |
+---------+------+SELECT gender, COUNT(DISTINCT product) AS dist_product, SUM(amount) AS total_amount FROM user_order GROUP BY gender;+---------+---------------+---------------+
| gender  | dist_product  | total_amount  |
+---------+---------------+---------------+
| 女       | 3             | 14500.0       |
| 男       | 4             | 3850.0        |
+---------+---------------+---------------+

2.3 高级查询

GROUP BY 后也可以跟上ROLLUOP /CUBE/GROUPING SETS进行高级查询。

  • ROLLUP:生成分组的层级汇总,包括总体汇总,适合需要分组和子分组汇总的场景。
#按照gender、age进行rollup查询
SELECT gender, age, SUM(amount) AS total_amount
FROM user_order
GROUP BY gender, age WITH ROLLUP;+---------+-------+---------------+
| gender  |  age  | total_amount  |
+---------+-------+---------------+
| 女       | 28    | 3200.0        |
| 女       | 30    | 11300.0       |
| 女       | NULL  | 14500.0       |
| 男       | 22    | 500.0         |
| 男       | 25    | 3350.0        |
| 男       | NULL  | 3850.0        |
| NULL    | NULL  | 18350.0       |
+---------+-------+---------------+
  • CUBE:生成所有可能的分组组合及其汇总,适合需要全方位查看数据的场景。
# CUBE 相当于给分组列进行所有可能组合的分组得到结果
SELECT gender, age, SUM(amount) AS total_amount  
FROM user_order
GROUP BY gender, age WITH CUBE;+---------+-------+--------------+
| gender  |  age  | total_amount  |
+---------+-------+--------------+
| 女       | 28    | 3200.0       |
| 女       | 30    | 11300.0      |
| 女       | NULL  | 14500.0      |
| 男       | 22    | 500.0        |
| 男       | 25    | 3350.0       |
| 男       | NULL  | 3850.0       |
| NULL    | 22    | 500.0        |
| NULL    | 25    | 3350.0       |
| NULL    | 28    | 3200.0       |
| NULL    | 30    | 11300.0      |
| NULL    | NULL  | 18350.0      |
+---------+-------+--------------+
  • GROUPING SETS:指定特定的分组组合,适合自定义分组组合场景。
#只按照grouping sets中指定的组合进行聚合数据
SELECT gender, age, SUM(amount) AS total_amount  
FROM user_order
GROUP BY gender, age
GROUPING SETS ((gender, age), (gender), ());+---------+-------+---------------+
| gender  |  age  | total_amount  |
+---------+-------+---------------+
| 女       | 28    | 3200.0        |
| 女       | 30    | 11300.0       |
| 女       | NULL  | 14500.0       |
| 男       | 22    | 500.0         |
| 男       | 25    | 3350.0        |
| 男       | NULL  | 3850.0        |
| NULL    | NULL  | 18350.0       |
+---------+-------+---------------

3. having

Having子句用于过滤“group by”聚合结果,Having与Where类似,但WHERE用于在分组之前过滤记录,而HAVING用于在分组之后过滤记录。使用HAVING可以基于聚合结果进行过滤。

案例:对user_order数据统计每个年龄消费金额,并保留消费金额大于500的年龄信息。

#统计每个年龄消费金额,保留消费金额大于500的年龄信息。
SELECT age, SUM(amount) AS total_amount  
FROM user_order
GROUP BY age
HAVING SUM(amount) > 500;+------+---------------+
| age  | total_amount  |
+------+---------------+
| 25   | 3350.0        |
| 28   | 3200.0        |
| 30   | 11300.0       |
+------+---------------+

4. 排序

Hive中与排序相关的操作有Order By、Sort By、Distribute By、Cluster By 几种操作,下面分别进行介绍。

4.1 数据准备

#准备如下数据
1,zs,30,北京,100
2,ls,25,上海,200
3,ww,35,广州,300
4,zl,40,广州,400
5,cq,28,北京,500
6,gb,33,广州,600
7,wj,22,广州,700
8,zs,29,北京,800
9,ly,31,上海,900
10,se,27,上海,1000

#Hive中创建user表,并将以上数据加载到表中
CREATE TABLE users (
    user_id INT,
    user_name STRING,
    age INT,
    city STRING,
    salary INT
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

load data inpath '/data.txt' into table users;

4.2 Order BY

Order By用于对整个查询结果进行全局排序,HQL转换成MapReduce任务只有一个Reduce,可能会导致性能瓶颈问题。严格模式下(hive.exec.dynamic.partition.mode=strict)Order By必须与limit一起使用,防止单个reduce处理过多数据。非严格模式下(hive.exec.dynamic.partition.mode=nonstrict,默认)虽然不强制跟上limit,也建议和limit一起使用。

#使用order by 对工资进行全局倒序排序。
SELECT user_id,user_name,age,city,salary  
FROM users 
ORDER BY salary desc;+----------+------------+------+-------+---------+
| user_id  | user_name  | age  | city  | salary  |
+----------+------------+------+-------+---------+
| 10       | se         | 27   | 上海    | 1000    |
| 9        | ly         | 31   | 上海    | 900     |
| 8        | zs         | 29   | 北京    | 800     |
| 7        | wj         | 22   | 广州    | 700     |
| 6        | gb         | 33   | 广州    | 600     |
| 5        | cq         | 28   | 北京    | 500     |
| 4        | zl         | 40   | 广州    | 400     |
| 3        | ww         | 35   | 广州    | 300     |
| 2        | ls         | 25   | 上海    | 200     |
| 1        | zs         | 30   | 北京    | 100     |
+----------+------------+------+-------+---------+

4.3 Sort By

Sort By可以对每个reduce的输出进行局部排序,数据在单个reduce中是有序地,即:每个reduce出来的数据时有序的,但全局可能不是有序的。在执行HQL时可以通过“set mapreduce.job.reduces=num;”来设置生成的MapReduce任务有几个Reduce。

#设置3个reduce 
set mapreduce.job.reduces=3;#查询表users中数据并写入到HDFS文件中,按照age进行sortBy排序
INSERT OVERWRITE directory '/data/' row FORMAT DELIMITED FIELDS TERMINATED BY ',' 
SELECT user_id,user_name,age,city,salary from users sort by age desc;#查看3个文件中数据,按照sort by 指定的age列降序排序
[root@hadoop101 ~]# hdfs dfs -cat /data/000000_0
6,gb,33,广州,600
9,ly,31,上海,900
8,zs,29,北京,800
5,cq,28,北京,500
10,se,27,上海,1000
7,wj,22,广州,700[root@hadoop101 ~]# hdfs dfs -cat /data/000001_0
4,zl,40,广州,400
3,ww,35,广州,300
2,ls,25,上海,200[root@hadoop101 ~]# hdfs dfs -cat /data/000002_0
1,zs,30,北京,100

以上语句查询完成后,由于设置有3个Reduce,所以可以在HDFS相应目录中看到有3个文件生成:

4.4 Distribute By

Distribute By可以跟上某列,按照该列对数据进行分区,不保证分区内的数据有序。Distribute By类似MapReduce中的自定义分区Partition,将相同的key数据发送到同一个Reduce Task中处理。Distribute By的分区规则是按照分区字段的hash码与reduce的个数进行取模,余数相同的分到一个区。

#设置3个reduce 
set mapreduce.job.reduces=3;#查询表users中数据并写入到HDFS文件中,按照city进行分区
INSERT OVERWRITE directory '/data/' row FORMAT DELIMITED FIELDS TERMINATED BY ',' SELECT user_id,user_name,age,city,salary from users distribute by city;#查看3个文件中数据city信息
[root@hadoop101 ~]# hdfs dfs -cat /data/000000_0
10,se,27,上海,1000
9,ly,31,上海,900
2,ls,25,上海,200[root@hadoop101 ~]# hdfs dfs -cat /data/000001_0[root@hadoop101 ~]# hdfs dfs -cat /data/000002_0
8,zs,29,北京,800
7,wj,22,广州,700
6,gb,33,广州,600
5,cq,28,北京,500
4,zl,40,广州,400
3,ww,35,广州,300
1,zs,30,北京,100

使用Distribute By时还可以跟上Sort By语句,指定每个分区中按照某列进行排序。以上数据我们发现相同城市数据去往了同一个文件,但是文件内的age是乱序的,所以可以在Distribute By后跟上Sort By指定按照age列进行排序。

#设置3个reduce 
set mapreduce.job.reduces=3;#Distribute By  + Sort By 一起使用
INSERT OVERWRITE directory '/data/' row FORMAT DELIMITED FIELDS TERMINATED BY ',' 
SELECT user_id,user_name,age,city,salary from users distribute by city sort by age desc;#以上执行完成后,查看每个文件中的数据,可以看到每个文件内的数据按照age降序排序
[root@hadoop101 ~]# hdfs dfs -cat /data/000000_0
9,ly,31,上海,900
10,se,27,上海,1000
2,ls,25,上海,200[root@hadoop101 ~]# hdfs dfs -cat /data/000001_0[root@hadoop101 ~]# hdfs dfs -cat /data/000002_0
4,zl,40,广州,400
3,ww,35,广州,300
6,gb,33,广州,600
1,zs,30,北京,100
8,zs,29,北京,800
5,cq,28,北京,500
7,wj,22,广州,700

4.5 Cluster By

当Distribute By和Sort By字段相同时,可以使用Cluster By 代替,但是排序只能是升序排序,不能指定排序为asc/desc。

#设置3个reduce 
set mapreduce.job.reduces=3;#对users表中age字段进行Cluster By操作
INSERT OVERWRITE directory '/data/' row FORMAT DELIMITED FIELDS TERMINATED BY ',' 
SELECT user_id,user_name,age,city,salary from users cluster by age;#等价于
INSERT OVERWRITE directory '/data/' row FORMAT DELIMITED FIELDS TERMINATED BY ',' SELECT user_id,user_name,age,city,salary from users distribute by age sort by age;[root@hadoop101 ~]# hdfs dfs -cat /data/000000_0
10,se,27,上海,1000
8,zs,29,北京,800
1,zs,30,北京,100
9,ly,31,上海,900
4,zl,40,广州,400[root@hadoop101 ~]# hdfs dfs -cat /data/000001_0
6,gb,33,广州,600[root@hadoop101 ~]# hdfs dfs -cat /data/000002_0
7,wj,22,广州,700
2,ls,25,上海,200
5,cq,28,北京,500
3,ww,35,广州,300

4.6 总结

  • Order By:全局排序,所有数据一个顺序,性能开销最大,适用于需要全局排序的情况。
  • Sort By:局部排序,每个reducer内排序,适用于大数据集的部分排序。
  • Distribute By:仅分区,不排序。
  • Cluster By:分区内排序,每个分区的数据由一个reducer排序,适用于需要数据按键分区的场景。
  • Order By和Sort By区别在于前者保证全局有序,后者仅保证Reducer内数据有序。
  • Distribute By的分区规则是根据分区字段的hash码与reduce的个数进行相除后,余数相同的分到一个区。
  • 如果Distribute By 、Sort By 排序字段一样,可以使用Cluster By 替代,即:Cluster By = Distribute By + Sort By,但Cluster By 排序只能是升序。

5. Hive Join

Hive中Join支持 [INNER] JOIN、LEFT [OUTER] JOIN、RIGHT [OUTER] JOIN、FULL [OUTER] JOIN、LEFT SEMI JOIN、CROSS JOIN ,下面通过一个案例来介绍LEFT SEMI JOIN、CROSS JOIN 。

LEFT SEMI JOIN - 左半开连接

LEFT SEMI JOIN 类似于 EXISTS 子查询,它返回左表中存在匹配行的行。右表只用于匹配,不包含在输出中。

#sql使用
SELECT *
FROM emp e
LEFT SEMI JOIN dept d ON e.dept_id = d.dept_id;#结果
+-----------+-------------+------------+
| e.emp_id  | e.emp_name  | e.dept_id  |
+-----------+-------------+------------+
| 1         | 张三          | 001        |
| 2         | 李四          | 002        |
| 3         | 王五          | 003        |
| 4         | 马六          | 004        |
+-----------+-------------+--------------+

6. UNION/UNION ALL

Union用于将多个Select语句的结果合并为一个结果集,union默认会删除重复行,union all不会删除重复行。

#union使用,重复行数据自动去重
select emp_id,emp_name from emp where emp_id in (1,2,3,4)
union
select emp_id,emp_name from emp where emp_id in (1,2,3);+---------+-----------+
| emp_id  | emp_name  |
+---------+-----------+
| 1       | 张三        |
| 2       | 李四        |
| 3       | 王五        |
| 4       | 马六        |
+---------+-----------+#union all,相同数据不去重
select emp_id,emp_name from emp where emp_id in (1,2,3,4)
union all 
select emp_id,emp_name from emp where emp_id in (1,2,3);+---------+-----------+
| emp_id  | emp_name  |
+---------+-----------+
| 1       | 张三        |
| 1       | 张三        |
| 2       | 李四        |
| 2       | 李四        |
| 3       | 王五        |
| 3       | 王五        |
| 4       | 马六        |
+---------+-----------+

7. hive视图

在Hive中如果经常使用到一个复杂SQL进行数据查询,我们可以对复杂SQL创建视图,这样就可以在后期使用中直接查询视图,比较方便。Hive中的视图与MySQL中的视图一样。

有两张表 student_info,student_score,对应数据及建表语句如下:

#student_info数据如下:
1	zs	18
2	ls	19
3	ww	20#student_info建表
create table student_info (id int,name string,age int) row format delimited fields terminated by '\t';
load data inpath '/student_info' into table student_info;#student_score数据如下:
1	zs	100
2	ls	200
3	ww	300#student_score建表
create table student_score (id int,name string,score int) row format delimited fields terminated by '\t';
load data inpath '/student_score' into table student_score;

假设我们经常需要使用如下结果:

select a.id,a.name,a.age,b.score from student_info a join student_score b on a.id = b.id

那么在Hive中经常使用以上查询,每次使用时都需要写一遍以上SQL执行,这里我们就可以直接创建Hive视图,方便后期查询。

Hive中创建视图语法如下:

CREATE VIEW [IF NOT EXISTS] [db_name.]view_name [(column_name [COMMENT column_comment], ...) ][COMMENT view_comment][TBLPROPERTIES (property_name = property_value, ...)]AS SELECT ... ;

我们可以针对以上场景创建视图“myview”:

#创建视图
create view myview as select a.id,a.name,a.age,b.score from student_info a join student_score b on a.id = b.id;#在后续使用中,直接使用视图myview即可
select * from myview;

在Hive中创建视图后,视图不是真正的表,不能加载数据操作,只是在Hive中保存了一份元数据,查询视图时执行对应的sql,视图不存储数据。

删除视图语法如下:

DROP VIEW [IF EXISTS] [db_name.]view_name;

删除创建的视图:

#我们可以将前面创建的视图删除
drop view myview;

8. 函数

Hive内置函数包括数学函数、集合函数、类型转换函数、日期函数、条件函数、字符串函数等。特别注意:Hive中所有的函数名称不区分大小写。

可以通过如下命令查询Hive中所有内置函数相关信息。

#查看Hive内置函数
show functions;#查看内置函数详细用法
desc function extended round;
+----------------------------------------------------+
|                      tab_name                      |
+----------------------------------------------------+
| round(x[, d]) - round x to d decimal places        |
| Example:                                           |
|   > SELECT round(12.3456, 1) FROM src LIMIT 1;     |
|   12.3'                                            |
| Function class:org.apache.hadoop.hive.ql.udf.generic.GenericUDFRound |
| Function type:BUILTIN                              |
+----------------------------------------------------+

8.1 数学函数

返回类型函数说明
BIGINTround(double a)四舍五入
DOUBLEround(double a,int d)小数部分d位之后数字四舍五入,例如round(21.263,2),返回21.26
BIGINTfloor(double a)对给定数据进行向下舍入最接近的整数。例如floor(21.8),返回21。
BIGINTceil(double a), ceiling(double a)将参数向上舍入为最接近的整数。例如ceil(21.2),返回22.
doublerand(), rand(int seed)返回大于或等于0且小于1的平均分布随机数(依重新计算而变)
doubleexp(double a)返回e的n次方
doubleln(double a)返回给定数值的自然对数
doublelog10(double a)返回给定数值的以10为底自然对数
doublelog2(double a)返回给定数值的以2为底自然对数
doublelog(double base, double a)返回给定底数及指数返回自然对数
doublepow(double a, double p)返回某数的乘幂
doublesqrt(double a)返回数值的平方根
stringbin(BIGINT a)返回二进制格式
stringhex(BIGINT a) hex(string a)将整数或字符转换为十六进制格式
stringunhex(string a)十六进制字符转换由数字表示的字符
stringconv(BIGINT num, int from_base,int to_base)将指定数值,由原来的度量体系转换为指定的体系。例如CONV('a',16,2),返回。参考:'1010'
doubleabs(double a)取绝对值
int doublepmod(int a, int b)返回a除b的余数的绝对值
doublesin(double a)返回给定角度的正弦值
doubleasin(double a)返回x的反正弦,即是X。如果X是在-1到1的正弦值,返回NULL。
doublecos(double a)返回余弦
doubleacos(double a)返回X的反余弦,即余弦是X,,如果-1<= A <= 1,否则返回null.
int doublepositive(int a) positive(double a)返回A的值,例如positive(2),返回2。
int doublenegative(int a) negative(double a)返回A的相反数,例如negative(2),返回-2。

8.2 类型转换函数

返回类型函数说明
指定的"type"cast(expr as)类型转换。例如将字符”1″转换为整数:cast('1' as bigint),如果转换失败返回NULL。如果转换(expr为布尔值),Hive对非空字符串返回true。

8.3 集合函数

返回类型函数说明
arraymap_keys(Map)返回map的所有key
arraymap_values(Map)返回map的所有value
intsize(Array(T))返回数组类型的元素数量
intsize(Map)返回的map类型的元素的数量
booleanarray_contains(Array, value)如果数组包含value则返回TRUE
arraysort_array(Array)根据数组元素的自然顺序按升序对输入数组进行排序并返回

8.4 日期函数

返回类型函数说明
stringfrom_unixtime(bigint unixtime[,stringpattern])UNIX_TIMESTAMP参数为秒,表示返回一个值'yyyy-MM– dd HH:mm:ss'格式。该值表示在当前的时区。
bigintunix_timestamp()获取以秒为单位的当前Unix时间戳(从'1970- 01–01 00:00:00'到现在的UTC秒数)为无符号整数。自2.0以来,已经被弃用了, 建议使用CURRENT_TIMESTAMP。
bigintunix_timestamp(string date)指定日期参数调用UNIX_TIMESTAMP(date),它返回参数值'1970-01–01 00:00:00'到指定日期的秒数。
bigintunix_timestamp(string date, string pattern)指定时间输入格式,返回'1970-01–01 00:00:00'到指定日期的秒数,:unix_timestamp('2024-07-24', 'yyyy-MM-dd') = ....
stringto_date(string timestamp)返回时间中的年月日:to_date("1970-01-01 00:00:00") = "1970-01-01"
intyear(string date)返回指定时间的年份,范围在1000到9999,例如:year("1970-01-01 00:00:00") = 1970, year("1970-01-01") = 1970
intquarter(date/timestamp/string)返回1到4范围内的日期、时间戳或字符串的季度。例如:quarter('1970-04-08') = 2。
intmonth(string date)返回指定时间的月份,范围为1至12月,例如:month("1970-11-01 00:00:00") = 11, month("1970-11-01") = 11。
intday(string date) dayofmonth(date)返回指定时间的日期,例如:day("1970-11-01 00:00:00") = 1, day("1970-11-01") = 1。
inthour(string date)返回指定时间的小时,范围为0到23。例如:hour('2009-07-30 12:58:59') = 12, hour('12:58:59') = 12。
intminute(string date)返回指定时间的分钟,范围为0到59。
intsecond(string date)返回指定时间的秒,范围为0到59。
intweekofyear(string date)返回指定日期所在一年中的星期号,范围为0到53。
intdatediff(string enddate, string startdate)两个时间参数的日期之差。
intdate_add(string startdate, int days)给定时间,在此基础上加上指定的时间段。
intdate_sub(string startdate, int days)给定时间,在此基础上减去指定的时间段。
datecurrent_date返回当前日期。
timestampcurrent_timestamp返回当前Unix时间戳。
stringdate_format(date/timestamp/string ts, string pattern)使用指定的pattern将date/timestamp/string转换为字符串值。例如:date_format('1970-04-08','y') = '1970'。

8.5 条件函数

返回类型函数说明
Tif(boolean testCondition, T valueTrue, T valueFalseOrNull)当testCondition为真时返回valueTrue,否则返回valueFalseOrNull
booleanisnull( a )如果a为NULL返回true,否则返回false。
booleanisnotnull ( a )如果a不为NULL则返回true,否则返回false
Tnvl(T value, T default_value)如果value为null则返回默认值,否则返回值
TCOALESCE(T v1, T v2, ...)返回第一个不为NULL的v,如果所有v都为NULL则返回NULL
TCASE a WHEN b THEN c [WHEN d THEN e]* [ELSE f] END当a = b,返回c;当a = d时,返回e;Else返回f
TCASE WHEN a THEN b [WHEN c THEN d]* [ELSE e] END当a为 true时,返回b;当c为true时,返回d;Else返回e
Tnullif( a, b )如果a=b,返回NULL;否则返回a

8.6 字符串函数

返回类型函数说明
stringconcat(string A, string B…)连接多个字符串,合并为一个字符串,可以接受任意数量的输入字符串
stringconcat_ws(string SEP, string A, string B…)链接多个字符串,字符串之间以指定的分隔符分开。
stringconcat_ws(string SEP, array)使用指定的分隔符连接array中的元素。
intfind_in_set(string str, string strList)返回字符串str第一次在strlist出现的位置。如果任一参数为NULL,返回NULL;如果第一个参数包含逗号,返回0。
stringget_json_object(string json_string, string path)根据指定的json路径从json字符串中提取json对象,并返回提取的json对象的json字符串。如果输入的json字符串无效,它将返回null。注意:json路径只能包含字符[0-9a-z_],即不能包含大写或特殊字符。例如:select a.timestamp, get_json_object(a.appevents, '.eventname') from log a;
intlength(string A)返回字符串的长度
stringlower(string A) lcase(string A)将文本字符串转换成字母全部小写形式
stringlpad(string str, int len, string pad)返回指定长度的字符串,给定字符串长度小于指定长度时,由指定字符从左侧填补。
stringrpad(string str, int len, string pad)返回指定长度的字符串,给定字符串长度小于指定长度时,由指定字符从右侧填补。
stringparse_url(string urlString, string partToExtract [, string keyToExtract])返回URL指定的部分。parse_url('http://facebook.com/path1/p.php?k1=v1&k2=v2#Ref1', 'HOST')返回:'facebook.com'
stringregexp_replace(string A, string B, string C)字符串A中的B字符被C字符替代
stringregexp_extract(string subject, string pattern, int index)通过下标返回正则表达式匹配的指定部分。regexp_extract('foothebar', 'foo(.*?)(bar)',2),匹配第二个捕获组所以返回'bar'
stringrepeat(string str, int n)重复N次字符串
stringreplace(string A, string OLD, string NEW)返回字符串A,并将所有不重叠的OLD替换为NEW。示例:select replace("ababab","abab", "Z");返回"Zab"。
stringreverse(string A)返回倒序字符串
stringspace(int n)返回指定数量的空格
arraysplit(string str, string pat)按照pat将字符串切分,转换为数组。
mapstr_to_map(text[, delimiter1, delimiter2])使用两个分隔符将文本分割为键值对。Delimiter1将文本分隔为K-V对,Delimiter2将每个K-V对分隔。delimiter1默认的分隔符是',';对于,delimiter2默认的分隔符是':'。
stringsubstr(string A, int start) substring(string A, int start)从文本字符串中指定的起始位置后的字符。
stringsubstr(string A, int start, int len) substring(string A, int start, int len)从文本字符串中指定的位置指定长度的字符。
stringtrim(string A)删除字符串两端的空格,字符之间的空格保留
stringltrim(string A)删除字符串左边的空格,其他的空格保留
stringrtrim(string A)删除字符串右边的空格,其他的空格保留
stringupper(string A) ucase(string A)将文本字符串转换成字母全部大写形式

8.7 数据掩码函数

数据掩码函数常用于数据脱敏。

返回类型函数说明
stringmask(string str[, string upper[, string lower[, string number]]])返回掩码版本的字符串。默认情况下,大写字母会转换为"X",小写字母会转换为 "x",数字会转换为 "n"。例如,mask("abcd-EFGH-8765-4321") 的结果是 xxxx-XXXX-nnnn-nnnn。你可以通过提供额外的参数来覆盖掩码中使用的字符:第二个参数控制大写字母的掩码字符,第三个参数控制小写字母的掩码字符,第四个参数控制数字的掩码字符。例如,mask("abcd-EFGH-8765-4321", "U", "l", "#") 的结果是 llll-UUUU-####-####。
stringmask_first_n(string str[, int n])返回掩码版本的字符串,其中前n个字符被掩码。大写字母会转换为 "X",小写字母会转换为 "x",数字会转换为 "n"。例如,mask_first_n("1234-5678-8765-4321", 4) 的结果是 nnnn-5678-8765-4321。
stringmask_last_n(string str[, int n])返回掩码版本的字符串,其中后n个字符被掩码。大写字母会转换为 "X",小写字母会转换为 "x",数字会转换为 "n"。例如,mask_last_n("1234-5678-8765-4321", 4) 的结果是 1234-5678-8765-nnnn。
stringmask_show_first_n(string str[, int n])返回掩码版本的字符串,其中前n个字符不被掩码(从 Hive 2.1.0 开始支持)。大写字母会转换为 "X",小写字母会转换为 "x",数字会转换为 "n"。例如,mask_show_first_n("1234-5678-8765-4321", 4) 的结果是 1234-nnnn-nnnn-nnnn。
stringmask_show_last_n(string str[, int n])返回掩码版本的字符串,其中后n个字符不被掩码。大写字母会转换为 "X",小写字母会转换为 "x",数字会转换为 "n"。例如,mask_show_last_n("1234-5678-8765-4321", 4) 的结果是nnnn-nnnn-nnnn-4321。
stringmask_hash(stringchar

8.8 复杂类型函数

Hive中常用复杂类型函数有如下几个:

函数操作类型说明
map(key1, value1, key2, value2, …)通过指定的键/值对,创建一个map。
struct(val1, val2, val3, …)通过指定的字段值,创建一个结构。结构字段名称默认为COL1,COL2,...
named_struct(name1,val1,name2,val2,...)通过指定的字段值,创建一个结构。结构字段名称为指定的name1,name2...,name和value需要成对出现。
array(val1, val2, …)通过指定的元素,创建一个数组。

复杂类型函数的操作符有如下几个:

运算符操作类型说明
A[n]A是一个数组,n为int型返回数组A的第n个元素,第一个元素的索引为0。如果A数组为['foo','bar'],则A[0]返回'foo'和A[1]返回'bar'。示例:select likes[0] from person;
M[key]M是Map,key是其中的K。返回关键值对应的值,例如map M为 {'f' -> 'foo', 'b' -> 'bar', 'all' -> 'foobar'},则M['all'] 返回'foobar'。示例:select address['beijing'] from person;
S.xS为struct返回结构x字符串在结构S中的存储位置。如 foobar {int foo, int bar} foobar.foo返回foo对应存储的整数。

9. Hive内置聚合函数(UDAF)

Hive中内置常用的聚合函数如下:

返回类型函数说明
bigintcount(*) ,count(expr), count(DISTINCT expr[, expr., expr.])返回记录条数。
doublesum(col),sum(DISTINCT col)求和
doubleavg(col),avg(DISTINCT col)求平均值
doublemin(col)返回指定列中最小值
doublemax(col)返回指定列中最大值
doublepercentile(BIGINTcol, p)返回数值区域的百分比数值点。0<=P<=1,否则返回NULL,不支持浮点型数值。
arraypercentile(BIGINT col, array(p1,[,p2]…))返回数值区域的一组百分比值分别对应的数值点。0<=P<=1,否则返回NULL,不支持浮点型数值。
doublevar_pop(col)返回指定列的方差
doublevar_samp(col)返回指定列的样本方差
doublestddev_pop(col)返回指定列的偏差
doublestddev_samp(col)返回指定列的样本偏差
doublecovar_pop(col1, col2)两列数值协方差
doublecovar_samp(col1, col2)两列数值样本协方差
doublecorr(col1, col2)返回两列数值的相关系数
arraycollect_set(col)返回无重复记录
arraycollect_list(col)返回所有记录,可以包含重复的记录

10. Hive内置表生成函数(UDTF)

普通的用户自定义函数(如 concat())会接收一行输入并输出一行结果。而表生成函数(UDTF,User Defined TableGenerating Functions)则会将单行输入转换为多行输出。

返回类型函数说明
Texplode(ARRAY a)将数组展开为多行。返回一个包含单列(col)的行集,数组中的每个元素对应一行。
Tkey,Tvalueexplode(MAP m)将映射展开为多行。返回一个包含两列(key和 value)的行集,输入映射中的每个键值对对应一行。
int,Tposexplode(ARRAY a)将数组展开为多行,并附加一个整数类型的位置信息列(表示元素在原数组中的位置,从0开始)。返回一个包含两列(pos 和 val)的行集,数组中的每个元素对应一行。
T1,...,Tninline(ARRAYSTRUCTf1:t1,...,fn:tn<> a)将结构体数组展开为多行。返回一个包含N列(N 是结构体中顶层元素的数量)的行集,数组中的每个结构体对应一行。
T1,...,Tn/rstack(int r,T1 V1,...,Tn/r Vn)将n个值 V1,...,Vn 分解为 r 行,第一个参数是行数,后面的参数是要拆分的值,每行将包含n/r列。r 必须是常量。
string1,...,stringnjson_tuple(string jsonStr,string k1,...,string kn)接收一个JSON字符串和一组 n 个键,返回一个包含 n 个值的元组。相比于 get_json_object UDF,这个函数更高效,因为它可以通过一次调用获取多个键的值。

案例如下:

#explode演示
SELECT explode(array(1, 2, 3)) as col;
+------+
| col  |
+------+
| 1    |
| 2    |
| 3    |
+------+SELECT explode(map('a', 1, 'b', 2)) as (key, value);
+------+--------+
| key  | value  |
+------+--------+
| a    | 1      |
| b    | 2      |
+------+--------+#posexplode演示
SELECT posexplode(array(1, 2, 3)) as (pos, val);
+------+------+
| pos  | val  |
+------+------+
| 0    | 1    |
| 1    | 2    |
| 2    | 3    |
+------+------+#inline演示
SELECT inline(array(named_struct('a', 1, 'b', 2), named_struct('a', 3, 'b', 4))) as (a, b);
+----+----+
| a  | b  |
+----+----+
| 1  | 2  |
| 3  | 4  |
+----+----+#stack演示
SELECT stack(2, 'a', 'b', 'c', 'd', 'e', 'f') as (col1, col2, col3);
+-------+-------+-------+
| col1  | col2  | col3  |
+-------+-------+-------+
| a     | b     | c     |
| d     | e     | f     |
+-------+-------+-------+#json_tuple演示
SELECT json_tuple('{"a":1, "b":2, "c":3}', 'a', 'b','c') as (a, b, c);
+----+----+----+
| a  | b  | c  |
+----+----+----+
| 1  | 2  | 3  |
+----+----+----+

11. LATERAL VIEW

准备如下案例:

#创建表
CREATE TABLE lateral_tbl (name STRING,scores ARRAY<INT>
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY ',';#向表中插入数据
insert into lateral_tbl values ('zs',array(1,2,3)),('ls',array(4,5,6));#查看表中数据
select * from lateral_tbl;
+-------------------+---------------------+
| lateral_tbl.name  | lateral_tbl.scores  |
+-------------------+---------------------+
| zs                | [1,2,3]             |
| ls                | [4,5,6]             |
+-------------------+---------------------+

针对以上表我们如果想要统计每个人对应的总得分,考虑可以先将scores列通过explode函数进行膨胀,然后按照name分组聚合。错误的SQL示例如下:

#如下SQL执行报错:UDTF's are not supported outside the SELECT clause, nor nested in expressions
select name,explode(scores)  from lateral_tbl;

以上SQL在Hive中不支持,主要原因是使用UDTF查询过程中Select后只能包含单个UDTF,不能包含其他字段以及多个UDTF的情况,即:select中不能有额外的列与UDTF函数一起使用。

Lateral View 就可以解决以上问题,Lateral View 可以和explode等UDTF函数一起使用,可以将一列数据拆成多行,将拆分的结果组成一个支持别名的虚拟表,在SQL查询中可以查询当前虚拟表。lateral view使用语法如下:

LATERAL VIEW udtf(expression) tableAlias AS columnAlias (',' columnAlias)*
  • tableAlias:虚拟表名称
  • columnAlias:udtf函数返回的列,如果是多个使用括号包裹起来多个列,括号内多列使用逗号分割。

以上需求正确的SQL如下:

#explode膨胀后数据
select name,score from lateral_tbl lateral view explode(scores) new_view as score;
--结果:
+-------+--------+
| name  | score  |
+-------+--------+
| zs    | 1      |
| zs    | 2      |
| zs    | 3      |
| ls    | 4      |
| ls    | 5      |
| ls    | 6      |
+-------+--------+#最终聚合sql
select name,sum(score) from lateral_tbl lateral view explode(scores) new_view as score group by name;
--结果:
+-------+------+
| name  | _c1  |
+-------+------+
| ls    | 15   |
| zs    | 6    |
+-------+------+

http://www.dtcms.com/a/406780.html

相关文章:

  • 网站维护 关站 seo百度首页广告
  • 搜索引擎的网站有哪些网页设计与网站建设 倪宝童
  • Prompt Optimizer 提示词优化器安装使用
  • 淘宝网站建设的优点app推广是什么工作
  • 【C++】23. C++11(上)
  • 第三方软件登记测评机构:【LoadRunner脚本录制与调试】
  • 摄影网站开发的背景西安网站 技术支持牛商网
  • A股大盘数据-20250925分析
  • 旋转设备状态监测传感器选型要点
  • echarts项目积累
  • VS2022调试技巧
  • Vue 3 组合式 API 生命周期钩子学习笔记
  • shardingsphere加载过程
  • MinerU介绍安装
  • 好的建设网站关于建立企业网站的方案内容
  • 在mac上面使用parquet-cli查看parquet文件
  • 织梦资讯门户网站模板公司成立后网站建设
  • linux入门4.4(DHCP和DNS服务器)
  • 存储卷备份策略在海外vps数据安全中的基础规范
  • 基于MATLAB的热晕相位屏仿真
  • 天津网站优化怎么样成都金牛区建设局网站
  • 惠州网站建设佳木斯自助个人免费网站
  • 学校网站源码html重庆seo哪个强
  • 基于Vue2的可视化大屏
  • AI+Decodo:构建智能电商价格监控系统的完整实战指南
  • 一般来说主键索引的树深度有几层?为什么是这个层数?
  • 【左程云算法笔记017】二叉树遍历递归写法
  • 加强门户网站建设的通知德州手机网站建设电话
  • 网站 备案 拍照系统开发过程中设计代码的原则为
  • 计算机网络---网络层