【Hive】——函数案例

1 Hive 多字节分隔符处理

1.1 默认规则

Hive默认序列化类是LazySimpleSerDe,其只支持使用单字节分隔符(char)来加载文本数据,例如逗号、制表符、空格等等,默认的分隔符为"\001"。根据不同文件的不同分隔符,我们可以通过在创建表时使用 row format delimited 来指定文件中的分割符,确保正确将表中的每一列与文件中的每一列实现一一对应的关系。

1.2 问题

  1. 每一行数据的分隔符是多字节分隔符,例如:"||"、"--"等
  2. 数据的字段中包含了分隔符

1.3 方案一:替换分隔符(不推荐)

直接解决数据问题,而不是解决了单字节分隔符问题,不推荐

1.4 方案二:RegexSerDe正则加载(推荐)

• 除了使用最多的LazySimpleSerDe,Hive该内置了很多SerDe类;

• 官网地址:https://cwiki.apache.org/confluence/display/Hive/SerDe

• 多种SerDe用于解析和加载不同类型的数据文件,常用的有ORCSerDe 、RegexSerDe、JsonSerDe等。

• RegexSerDe用来加载特殊数据的问题,使用正则匹配来加载数据。

• 根据正则表达式匹配每一列数据。

https://cwiki.apache.org/confluence/display/Hive/GettingStarted#GettingStarted-ApacheWeblogData

sql 复制代码
create table singer(id string,--歌手id
                    name string,--歌手名称
                    country string,--国家
                    province string,--省份
                    gender string,--性别
                    works string)--作品
--指定使用RegexSerde加载数据
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES ("input.regex" = "([0-9]*)\\|\\|(.*)\\|\\|(.*)\\|\\|(.*)\\|\\|(.*)\\|\\|(.*)");
sql 复制代码
create table apachelog(
                          ip string,      --IP地址
                          stime string,    --时间
                          mothed string,  --请求方式
                          url string,     --请求地址
                          policy string,  --请求协议
                          stat string,    --请求状态
                          body string     --字节大小
)
--指定使用RegexSerde加载数据
    ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
--指定正则表达式
        WITH SERDEPROPERTIES (
        "input.regex" = "([^ ]*) ([^}]*) ([^ ]*) ([^ ]*) ([^ ]*) ([0-9]*) ([^ ]*)"
        ) stored as textfile ;

2 URL解析函数

2.1 URL基本组成

2.2 parse_url函数

2.2.1 功能

parse_url函数是Hive中提供的最基本的url解析函数,可以根据指定的参数,从URL解析出对应的参数值进行返回,函数为普通的一对一函数类型。

2.2.2语法

sql 复制代码
parse_url(url, partToExtract[, key]) - extracts a part from a URL 
Parts: HOST, PATH, QUERY, REF, PROTOCOL, AUTHORITY, FILE, USERINFO key 

2.2.3 案例

sql 复制代码
SELECT parse_url('http://facebook.com/path/p1.php?id=10086', 'HOST');

SELECT parse_url('http://facebook.com/path/p1.php?id=10086&name=allen', 'QUERY') ;

SELECT parse_url('http://facebook.com/path/p1.php?id=10086&name=allen', 'QUERY', 'name') ;
sql 复制代码
select
   id,
   parse_url(url,"HOST") as host,
   parse_url(url,"PATH") as path,
   parse_url(url,"QUERY") as query
 from
  tb_url;

2.3 parse_url_tuple

2.3.1 功能

parse_url_tuple函数是Hive中提供的基于parse_url的url解析函数,可以通过一次指定多个参数,从URL解析出多个参数的值进行返回多列,函数为特殊的一对多函数类型,即通常所说的UDTF函数类型。

2.3.2语法

sql 复制代码
parse_url_tuple(url, partname1, partname2, ..., partnameN) - extracts N (N>=1) parts from a URL.
 It takes a URL and one or multiple partnames, and returns a tuple.

2.3.3 案例

sql 复制代码
--建表
create table tb_url(
    id int,
    url string
)row format delimited
fields terminated by '\t';
--加载数据
load data local inpath '/root/hivedata/url.txt' into table tb_url;

select * from tb_url;

select parse_url_tuple(url,"HOST","PATH") as (host,path) from tb_url;

select parse_url_tuple(url,"PROTOCOL","HOST","PATH") as (protocol,host,path) from tb_url;

select parse_url_tuple(url,"HOST","PATH","QUERY") as (host,path,query) from tb_url;

3 UDTF函数问题

Hive中的一对多的UDTF函数可以实现高效的数据转换,但是也存在着一些使用中的问题,UDTF函数对于很多场景下有使用限制,例如:select时不能包含其他字段、不能嵌套调用、不能与group by等放在一起调用等等。

UDTF函数的调用方式,主要有以下两种方式:

3.1 直接在select后单独使用

sql 复制代码
--parse_url_tuple
select
    id,
    parse_url_tuple(url,"HOST","PATH","QUERY") as (host,path,query)
from tb_url;

3.2 与Lateral View放在一起使用

sql 复制代码
--单个lateral view使用
select
    a.id as id,
    b.host as host,
    b.path as path,
    b.query as query
from tb_url a lateral view parse_url_tuple(url,"HOST","PATH","QUERY") b as host,path,query;

--多个lateral view
select
    a.id as id,
    b.host as host,
    b.path as path,
    c.protocol as protocol,
    c.query as query
from tb_url a
         lateral view parse_url_tuple(url,"HOST","PATH") b as host,path
         lateral view parse_url_tuple(url,"PROTOCOL","QUERY") c as protocol,query;

4 Lateral View

如果UDTF不产生数据时,这时侧视图与原表关联的结果将为空

sql 复制代码
---Outer Lateral View
--如果UDTF不产生数据时,这时侧视图与原表关联的结果将为空
select
    id,
    url,
    col1
from tb_url
         lateral view explode(array()) et as col1;

如果加上outer关键字以后,就会保留原表数据,类似于outer join

sql 复制代码
--如果加上outer关键字以后,就会保留原表数据,类似于outer join
select
    id,
    url,
    col1
from tb_url
         lateral view outer explode(array()) et as col1;

5 行列转换

5.1 多行转多列(case when)

case when 函数:用于实现对数据的判断,根据条件,不同的情况返回不同的结果,类似于Java中的switch case 功能

sql 复制代码
CASE 
 WHEN 条件1 THEN VALUE1
......
WHEN 条件N THEN VALUEN
ELSE 默认值  END
sql 复制代码
CASE 列
WHEN V1 THEN VALUE1
......
WHEN VN THEN VALUEN
ELSE 默认值  END

5.2 多行转单列(concat_ws、collect_list、collect_set)

  1. concat_ws 函数: 用于实现字符串拼接,可以指定分隔符
    特点:任意一个元素不为null,结果就不为null
sql 复制代码
concat_ws(SplitChar,element1,element2......)
sql 复制代码
select concat_ws("-","itcast","And","heima");
+-------------------+
| itcast-And-heima  |
+-------------------+
sql 复制代码
select concat_ws("-","itcast","And",null);

±------------+

| itcast-And |

±------------+

  1. collect_list 函数: 用于将一列中的多行合并为一行,不进行去重
sql 复制代码
collect_list(colName)
sql 复制代码
select collect_list(col1) from row2col1;

±---------------------------+

| ["a","a","a","b","b","b"] |

±---------------------------+

  1. collect_set 函数: 用于将一列中的多行合并为一行,并进行去重
sql 复制代码
collect_set(colName)
sql 复制代码
select collect_set(col1) from row2col1;

±-----------+

| ["b","a"] |

±-----------+

5.3 多列转多行(union、union all)

5.4 单列转多行(explode)

6 json处理

6.1 概述

JSON数据格式是数据存储及数据处理中最常见的结构化数据格式之一,很多场景下公司都会将数据以JSON格式存储在HDFS中,当构建数据仓库时,需要对JSON格式的数据进行处理和分析,那么就需要在Hive中对JSON格式的数据进行解析读取。

6.2 JSON 函数处理

适用于将数据作为一个JSON字符串加载到表中,再通过JSON解析函数对JSON字符串进行解析

6.2.1 get_json_object

  1. 功能: 用于解析JSON字符串,可以从JSON字符串中返回指定的某个对象列的值
  2. 语法: get_json_object(json_txt, path) - Extract a json object from path
  3. json_txt:指定要解析的JSON字符串,path:指定要返回的字段,通过$.columnName的方式来指定path
  4. 特点:每次只能返回JSON对象中一列的值
sql 复制代码
select
    --获取设备名称
    get_json_object(json,"$.device") as device,
    --获取设备类型
    get_json_object(json,"$.deviceType") as deviceType,
    --获取设备信号强度
    get_json_object(json,"$.signal") as signal,
    --获取时间
    get_json_object(json,"$.time") as stime
from tb_json_test1;

6.2.2 json_tuple

  1. 功能:用于实现JSON字符串的解析,可以通过指定多个参数来解析JSON返回多列的值
  2. 语法:json_tuple(jsonStr, p1, p2, ..., pn) like get_json_object, but it takes multiple names and return a tuple
  3. 参数:jsonStr:指定要解析的JSON字符串;p1:指定要返回的第1个字段;pn:指定要返回的第n个字段
  4. 特点:功能类似于get_json_object,但是可以调用一次返回多列的值,属于UDTF类型函数,一般搭配lateral view使用,返回的每一列都是字符串类型
sql 复制代码
--json_tuple
 --单独使用
select
    --解析所有字段
    json_tuple(json,"device","deviceType","signal","time") as (device,deviceType,signal,stime)
from tb_json_test1;

--搭配侧视图使用
select
    json,device,deviceType,signal,stime
from tb_json_test1
         lateral view json_tuple(json,"device","deviceType","signal","time") b
         as device,deviceType,signal,stime;

6.3 JSONSerde

Hive中为了简化对于JSON文件的处理,内置了一种专门用于解析JSON文件的Serde解析器,在创建表时,只要指定使用JSONSerde解析表的文件,就会自动将JSON文件中的每一列进行解析。

sql 复制代码
--JsonSerDe
 --创建表
create table tb_json_test2 (
                               device string,
                               deviceType string,
                               signal double,
                               `time` string
)
    ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'
    STORED AS TEXTFILE;

load data local inpath '/root/hivedata/device.json' into table tb_json_test2;
相关推荐
B站计算机毕业设计超人1 小时前
计算机毕业设计hadoop+spark知网文献论文推荐系统 知识图谱 知网爬虫 知网数据分析 知网大数据 知网可视化 预测系统 大数据毕业设计 机器学习
大数据·hadoop·爬虫·机器学习·spark·知识图谱·推荐算法
Yz98761 小时前
Hadoop里面MapReduce的序列化与Java序列化比较
java·大数据·jvm·hadoop·分布式·mapreduce·big data
Yz98764 小时前
Hadoop-MapReduce的 原理 | 块和片 | Shuffle 过程 | Combiner
大数据·数据库·数据仓库·hadoop·mapreduce·big data
RestCloud6 小时前
一文说清楚ETL与Kafka如何实现集成
数据仓库·kafka·etl·数据处理·数据集成
CaritoB6 小时前
中台架构下的数据仓库与非结构化数据整合
数据仓库·架构
人生百态,人生如梦20 小时前
大数据处理从零开始————3.Hadoop伪分布式和分布式搭建
hadoop·分布式
天地风雷水火山泽1 天前
二百六十六、Hive——Hive的DWD层数据清洗、清洗记录、数据修复、数据补全
数据仓库·hive·hadoop
大数据深度洞察1 天前
Hive企业级调优[2]—— 测试用表
数据仓库·hive·hadoop
lzhlizihang1 天前
使用sqoop将mysql数据导入到hive报错ClassNotFoundException、Zero date value prohibited等错误
hive·报错·sqoop
goTsHgo1 天前
Hive自定义函数——简单使用
大数据·hive·hadoop