Hive DDL和简单函数

一、DDL操作

1、修改表

    1、1增加分区

--一次添加一个分区
    alter table tablename add partition (dt='20000202') location '要填在的表在hafs上的实际路径';

--一次添加多个分区
    alter table tabelname add 
 partition (year='2019',month='09',day='18') location '表的路径/year=2019/month=09/day=18' 
 partition (yaer='2018',month='09',day='17') location '标的路径/yaer=2018/month=09/day=17';

 

    1、2删除分区

alter table tablename drop if exists partition (guojia='china');

2、显示命令

-- 查看分区
show partition tablename;
-- 查看表信息
desc extended tablename;
-- 查看表信息(格式化美观)
desc formatted tablename;
-- 查看数据库相关信息
describe database databasename;

二、DML操作

1、数据加载的三种方式

                    1)hdfs dfs -put 

                    2)  load data local inpath 'filepath'

                    3)  insert + select

 

Load

-- 语法格式
    load data [local] inpath 'filepath' [overwrite] into table tablename [partition(formatted )];
    
    1、local
        如果指定了local 那么文件的路径就是在本地的文件路径
        如果没有指定local 那么filepath将会是hdfs中的路径
    2、overwrite
        如果添加  那么将会把目标表中的数据删除
        如果不添加 那么数据将会在目标表的后面追加数据
   

insert

-- hive中国insert主要是和select一起使用的
    insert overwrite table tablename select * from tablename;

-- 可以将查询出来的数据添加到原表中  这就相当于自我复制了一分数据
    from tablename
    insert overwrite table tablename1 [partition (...)]
    select语句
    insert overwrite table tablename2 [partition (....)]
    select语句
-- 动态分区插入

select

-- 基本的select操作
-- 语法结构
    SELECT [ALL | DISTINCT] select_expr, select_expr, ...
    FROM table_reference
    JOIN table_other ON expr
    [WHERE where_condition]
    [GROUP BY col_list [HAVING condition]]
    [CLUSTER BY col_list
    | [DISTRIBUTE BY col_list] [SORT BY| ORDER BY col_list]
    ]
    [LIMIT number]

1、order by会对全局的数据进行排序
2、sort by 其在数据进入reduce前完成排序 
3、distribute by(字段) 根据指定的字段将数据分发到不同的分区,分发算法是hash散列
4、cluster(字段) = 2 + 3
-- 如果distribute 和sort的字段相同   此时就相当于cluster by = distribute by + sort by

 

2、hive join

-- inner join 内连接 两张表都满足的数据
-- left join 左连接 以左表为主表 主表的数据都显示
-- left semi join 显示左表的数据部分
-- join 发生在where句子之前

 

三、hive的参数配置

1、hive shell 命令行

                因为在hive中输入很多命令的时候是很不方便的 这时就要针对这一方面进行一个补充

               输入$HIVE_HOME/bin/hive -H 或者-help来查看命令

1、 -i 初始化HQL文件
2、 -e 从命令行来执行指定的HQL
3、 -f 执行HQL脚本   把相应的脚本程序上传到本地
4、 -v 输出执行的HQL语句到控制台

eg:
$HIVE_HOME/bin/hive -e 'select * from tab1 a'
$HIVE_HOME/bin/hive -f /home/my/hive-script.sql
$HIVE_HOME/bin/hive -f hdfs://<namenode>:<port>/hive-script.sql
$HIVE_HOME/bin/hive -i /home/my/hive-init.sql

 

四、函数入门

1、条件函数

                 

-- if函数
    
    语法:if(bolean testcondition, T valuetrue, T value);
    当条件testCondition为true时 返回valuetrue,否则返回value
-- 非空查找函数 coalesce
    说明:返回参数中的第一个非空值
    eg:hive> select COALESCE(null,'100','50′) from dual;
-- 条件判断函数
    语法:case a when b then c [when d then e]* [else f] end;

2、字符串函数

-- 字符串长度函数:length
-- 反转函数:reverse
-- 连接函数:concat
-- 带分隔符连接函数:concat——ws
-- 字符串截取函数: substr
-- 转大写函数:upper
-- 转小写函数:lower
-- 去空格函数:trim
-- 左边去空格函数:ltrim
-- 右边去空格函数:rtrim
-- 正则表达式替换函数:regexp replace
-- 正则表达式解析函数:regexp extract
-- URL解析函数:parse url
-- json解析函数:get json object

 

3、Hive自定义函数

        当hive提供的内置函数无法满足业务需求的时候就要使用自定义函数

               3.1自定函数的分类

                       1)UDF( User-Defined-Function) 普通函数 一进一出

                       2)UDAF( User-Defined Aggregation Function) 聚合函数,多进一出

                       3)UDTF( User-Defined Table-Generating Functions) 表生成函数 一进多出

        3.2 UDF开发实例

                1)新建maven项目

                2)添加 hive-exec-1.2.1.jar 和 hadoop-common-2.7.4.jar 依赖

                3)写一个java类 继承UDF 并重载 evaluate 方法

                4)打成 jar 包上传到服务器

                5)将jar包添加到hive的classpath   hive>add JAR   /home/hadoop/udf.jar;

                6)创建临时函数与开发好的java class 关联 

create temporary function 函数名 as 'cn.itcast.bigdata.udf.类名';

                7)在hql中使用自定义的函数   select  上面定义的函数名(name),age from 表名;

4、Hive特殊分隔符处理

              hive 读取数据的机制

    首先用 InputFormat<默认是: org.apache.hadoop.mapred.TextInputFormat >的一
个具体实现类读入文件数据,返回一条一条的记录(可以是行,或者是你逻辑中的“行”)
    然后利用 SerDe<默认: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe>
的一个具体实现类,对上面返回的一条一条的记录进行字段切割

eg:
    01||zhangsan
    02||lisi

可用使用 RegexSerDe 通过正则表达式来抽取字段


drop table t_bi_reg;
create table t_bi_reg(id string,name string)
row format serde 'org.apache.hadoop.hive.serde2.RegexSerDe'
with serdeproperties(
'input.regex'='(.*)\\|\\|(.*)',
'output.format.string'='%1$s %2$s'
)
stored as textfile;
hive>load data local inpath '/root/hivedata/bi.dat' into table t_bi_reg;
hive>select * from t_bi_reg;

其中:
input.regex:输入的正则表达式
    表示 || 左右两边任意字符被抽取为一个字段
output.format.string:输出的正则表达式
    %1$s %2$s 则分别表示表中的第一个字段、第二个地段
注意事项:
    a、使用 RegexSerDe 类时,所有的字段必须为 string
    b、 input.regex 里面,以一个匹配组,表示一个字段

5、函数高阶特性

                5.1UDTF函数- explode

                    UDTF 函数,用户自定义表生成函数。可以将一行转成一行多列,也可以将一行转成多行多列,使用频率较高。 除了用户可以自定义这样的函数之外, hive也自带了很多 UDTF 函数, 便于在各种场合针对数据进行解析分析。

                    explode 函数就是 hive 内置的一个 UDTF 函数。 其可以将一个 array 或者 map类型的字段展开,其中 explode(array)使得结果中将 array 列表里的每个元素生成一行; explode(map)使得结果中将 map 里的每一对元素作为一行, key 为一列,value 为一列。
                    一般情况下,直接使用 explode 即可,也可以根据需要结合 lateral view。
 

使用:
  
-- 准备数据:
    001,allen,usa|china|japan,1|3|7
    002,kobe,usa|england|japan,2|3|5

-- 创建表和导入数据
    create table test_message (id int,name string,location array<string>,city array<string>) row format delimited fields terminated by "," collection items terminated by "|";
    load data local inpath "数据文件的路径" into table test_message;

-- 查看元素
    select explode(location) from test_message;


注意:
select name,explode(location) from test_message; 报错
当使用UDTF函数的时候,hive只允许对拆分字段进行访问的。

结果:

                     

5.2 lateral view函数(列转行)

                lateral view为侧视图 ,意义是为了配合UDTF来使用,把莫一行数据拆分成多行数据,不加lateral view的UDTF只能提取单个字段拆分,并不能塞回原来数据表中,加上lateral view就可以将拆分的单个字段数据与原始表数据关联上。

                注意:在使用lateral view的时候需要制定视图别名和生成的新列别名

-- 如果不加lateral view  就会只是提取单个字段的数据对其进行拆分

                 

-- 如果加入lateral view的时候就可以将拆分的单个字段的数据和源数据进行关联

eg:
    select * from 真实表名 lateral view explode(loction) 虚拟表的别名; 

    select t.id,t.name,subview.aaa from test_message t lateral view explode(location) subview as aaa;

结果:

5.3 行转列   多行转单列

      需要使用的hive内置函数

          concat_ws(参数1,参数2,参数3.。。。。)用于进行字符创的拼接   拼接的时候每个参数的中间使用参数1的内容进行分割

          collect_set(col3)

                   他的主要作用就是将某字段的值进行去重汇总,产生array类型的字段,如果不想去重可用 collect_list()


数据:

a,b,1
a,b,2
a,b,3
c,d,4
c,d,5
c,d,6
创建表:
create table row2col_1(col1 string,col2 string,col3 int) row format delimited fileds terminated by ',';
加载数据:
load data local inpath '文件路径' into table row2col_1;

select collect_set(col3) from row2col_1;
--将col3的所有数据放到一个集合中(去重)
[1,2,3,4,5,6]

select collect_set(col3) from row2col_1 group by col1,col2;
--根据col1,col2进行分组,只有第一列和第二列都相同,认为是同一组
[1,2,3]
[4,5,6]
select col1,col2, collect_set(col3) from row2col_1 group by col1,col2;
--行转列
a    b    [1,2,3]
c    d    [4,5,6]

select col1,col2, concat_ws(',',collect_set(cast(col3 as string))) as col3 from row2col_1 group by col1,col2;

a    b    1,2,3
c    d    4,5,6
cast(col3 as string)
collect_set(字符串类型的col3)
concat_ws(',',['col3'])

5.4 reflect函数

reflect函数可以支持在sql中调用java中的自带函数,秒杀一切udf函数

     5.4.1 使用java.lang.math当中的max求两列中最大值

-- 创建表
    create table test_udf(col1 int,col2 int) row format delimited fields terminated by ',';

-- 准备数据

    test——udf.txt
    1,2
    4,3
    6,4
    7,5
    5,6
--加载数据

load data local inpath 'test——udf.txt在本地的路径' into table test_udf;

-- 求最大值

select reflect("java.lang.Math","max",col1,col2) from test_udf;

    --1.使用java中的哪个类
	--2.类中的方法
	--3.方法中的参数

    5.4.2 不同记录执行不同的 java 内置函数

-- 创建表
 create table test_udf2(class_name string,method_name string,col1 int,col2 int) row format delimited fields terminted by ',';

--准备数据 test_udf2.txt
java.lang.Math,min,1,2
java.lang.Math,max,2,3

--加载数据
 load data local inpath 'test_udf2.txt文件所在的路径' into table test_ud2;

-- 执行查询

select reflect(class_name,method_name,col1,col2) from test_udf2;

 

 

6 、json 数据解析 (原声的js对象)

                 json数据解析总的来说有两方式来做;

                 1、将json数据已字符串的方式整个入hive表 ,然后通过使用udf 函数解析已经导入到hive中的数据,比如使用 LATERAL VIEW json_tuple 的方法,获取所需要的列名。

               get_json_object(string json_string,string path)

                json_tuple(string json_string,'属性1','属性2')

-- 数据
    {
     "id":1701439105,
     "ids":[2154137571,3889177061,1496915057,1663973284],
     "total_number":493
     }
-- 创建表
    create table if not exists tmp_json_test(json string) stored as testfile;

--加载数据
    load data local inpath '数据文件所在的路径' overwrite into table tmp_json_test;

-- 查询数据

    select get_json_object(t.json.'$.id'),get_json_object(t.json,'$.total_number') from tmp_json_test t;
   
    或者
    select json_tuple(json,'id','ids','total_number') from tmp_json_test; // 方便使用

          2、在导入之前将json拆成各个字段,导入hive表的数据已经解析过的,这将需要第三方的serde;

 

http:www.congiu.net/hive-json-serde/

add jar /root/hivedata/json-serde-1.3.7-jar-with-dependencies.jar;

create table tmp_json_array(id string,ids array<string>,total_number int) 
row format SERDE 'org.openx.data.jsonserde.JsonSerDe' 
stored as textfile;



load data local inpath '/root/hivedata/json_test.txt' overwrite into table tmp_json_array;


注意:json表的创建依赖jar需要调整设置

<https://blog.csdn.net/xingyue0422/article/details/86479990>

 

使用explode函数解析json数组

SELECT explode(split(regexp_replace(regexp_replace('[{"website":"www.baidu.com","name":"百度"},{"website":"google.com","name":"谷歌"}]', '\\]',''),'\\}\\,\\{','\\}\\;\\{'),'\\;'));


'[{"website":"www.baidu.com","name":"百度"},{"website":"google.com","name":"谷歌"}]'
1.将字符串变成数组

regexp_replace('[{"website":"www.baidu.com","name":"百度"},{"website":"google.com","name":"谷歌"}]', '\\]','')
regexp_replace('字符串','字符串中包含的内容','替换的内容')
'[{"website":"www.baidu.com","name":"百度"},{"website":"google.com","name":"谷歌"}'

regexp_replace('{"website":"www.baidu.com","name":"百度"},{"website":"google.com","name":"谷歌"}','\\}\\,\\{','\\}\\;\\{')
{"website":"www.baidu.com","name":"百度"};{"website":"google.com","name":"谷歌"}


split('{"website":"www.baidu.com","name":"百度"};{"website":"google.com","name":"谷歌"}',';');
'[{"website":"www.baidu.com","name":"百度"}','{"website":"www.baidu.com","name":"百度"}'

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值