hive常用函数

行列转换

在这里插入图片描述

create table tmp_summer1(id string,name string brith string);

insert into tmp_summer1 values('001','A','20211202');
insert into tmp_summer1 values('001','B','20211202');
insert into tmp_summer1 values('002','A','20211202');
insert into tmp_summer1 values('001','B','20211202');

在这里插入图片描述

多行合并一行

--collect_set去重
-- 如果字段不是string类型则转: cast(c1 as string)
create table tmp_summer2 as 
select id
    ,concat_ws('&',collect_set(name)) as name
    ,max(brith) as brith
from tmp_summer1 a
group by id;       
 
--collect_list不去重          
select id
    ,concat_ws('&',collect_list(name)) as name
    ,max(brith) as brith
from tmp_summer1 a
group by id;  

在这里插入图片描述

--列转行
create table tmp_summer3 as 
select id,name_split,brith
from tmp_summer2
lateral view explode(split(name,'&')) tmpTable as name_split

在这里插入图片描述

--将一列拆分为多列
create table tmp_summer4 as 
select id
    ,max(case when name_split='A' then name_split else null end) as name_a
    ,max(case when name_split='B' then name_split else null end) as name_b
    ,max(case when name_split='C' then name_split else null end) as name_c
    ,max(brith) as brith
from tmp_summer3
group by id;

解析JSON

-- get_json_object(json_string, '$.key')
-- 功能:解析json的字符串json_string,返回key指定的内容。如果输入的json字符串无效,那么返回NULL。这个函数每次只能返回一个数据项。
SELECT 
GET_JSON_OBJECT('{"level":"2","time":1650973942596,"type":"0"}','$.level' ) as level ;

日期函数

2021-09-16 00:00:00        ——>        20210916
to_char(ZHTCJSJ,'yyyymmdd')    ——>   from_unixtime(unix_timestamp(ZHTCJSJ),'yyyyMMdd')

from_unixtime(unix_timestamp(date1),'yyyyMMdd')
-- 当前日期	
select current_date; --// 2021-12-23 
select unix_timestamp(); --// 1640224807
-- 建议使用current_timestamp,有没有括号都可以
select current_timestamp(); --// 2021-12-23 09:57:57.638 

-- 时间戳转日期
select from_unixtime(1505456567); --//2017-09-15 14:22:47
select from_unixtime(1505456567, 'yyyyMMdd'); --//20170915
select from_unixtime(1505456567, 'yyyy-MM-dd HH:mm:ss'); --// 2017-09-15 14:22:47

-- 日期转时间戳
select unix_timestamp('2019-09-15 14:23:00'); --//1568528580

-- 计算时间差
select datediff('2020-04-18','2019-11-21'); --//149
select datediff('2019-11-21', '2020-04-18'); --//-149

-- 查询该天是该月第几天
select dayofmonth(current_date); --//23
select dayofmonth('2021-12-23'); --//21

-- 计算月末:
select last_day(current_date); --//2021-12-31
select last_day('2021-12-15'); --//2021-12-31

-- 当月第1天:
select date_sub(current_date, dayofmonth(current_date)-1) --//2021-12-01
-- 下个月第1天:
select add_months(date_sub(current_date, dayofmonth(current_date)-1), 1);
 --//2022-01-01

-- 字符串转时间(字符串必须为:yyyy-MM-dd格式)
select to_date('2020-01-01');
select to_date('2020-01-01 12:12:12');

-- 日期、时间戳、字符串类型格式化输出标准时间格式
select date_format(current_timestamp(), 'yyyy-MM-dd HH:mm:ss');
select date_format(current_date(), 'yyyyMMdd');
select date_format('2020-06-01', 'yyyy-MM-dd HH:mm:ss');

-- 计算emp表中,每个人的工龄
select *, round(datediff(current_date, hiredate)/365,1) as workingyears 
from emp;

字符串函数

-- 转小写。lower
select lower("HELLO WORLD");
-- 转大写。upper
select lower(ename), ename from emp;

-- 求字符串长度。length
select length(ename), ename from emp;
-- 字符串拼接。 concat / ||
select empno || " " ||ename idname from emp;
select concat(empno, " " ,ename) idname from emp;

-- 指定分隔符。concat_ws(separator, [string | array(string)]+) 
SELECT concat_ws('.', 'www', array('lagou', 'com'));
select concat_ws(" ", ename, job) from emp;

-- 求子串。substr
SELECT substr('www.lagou.com', 5); 
SELECT substr('www.lagou.com', -5); 
SELECT substr('www.lagou.com', 5, 5);

-- 字符串切分。split,注意 '.' 要转义
select split("www.lagou.com", "\\.");

数学函数

-- 四舍五入。round
select round(314.15926); 
select round(314.15926, 2); 
select round(314.15926, -2);
-- 向上取整。ceil
select ceil(3.1415926);
-- 向下取整。floor
select floor(3.1415926);
-- 其他数学函数包括:绝对值、平方、开方、对数运算、三角运算等

条件函数

-- if (boolean testCondition, T valueTrue, T valueFalseOrNull)
select sal, if (sal<1500, 1, if (sal < 3000, 2, 3)) from emp;
-- CASE WHEN a THEN b [WHEN c THEN d]* [ELSE e] END
-- 将emp表的员工工资等级分类:0-1500、1500-3000、3000以上
select sal, if (sal<=1500, 1, if (sal <= 3000, 2, 3)) from emp;
 
-- CASE WHEN a THEN b [WHEN c THEN d]* [ELSE e] END -- 复杂条件用 case when 更直观
select sal, case when sal<=1500 then 1
                 when sal<=3000 then 2
                 else 3 end sallevel
from emp;
 
-- 以下语句等价
select ename, deptno,
       case deptno when 10 then 'accounting'
                   when 20 then 'research'
                   when 30 then 'sales'
                   else 'unknown' end deptname
from emp;
 
select ename, deptno,
       case when deptno=10 then 'accounting'
            when deptno=20 then 'research'
            when deptno=30 then 'sales'
            else 'unknown' end deptname
from emp;
 
-- COALESCE(T v1, T v2, ...)。返回参数中的第一个非空值;如果所有值都为 NULL,那么返回NULL
select sal, coalesce(comm, 0) from emp;
-- isnull(a) isnotnull(a)
select * from emp where isnull(comm);
select * from emp where isnotnull(comm);
-- nvl(T value, T default_value)
select empno, ename, job, mgr, hiredate, deptno, sal + nvl(comm,0) sumsal from emp;
-- nullif(x, y) 相等为空,否则为a
SELECT nullif("b", "b"), nullif("b", "a");

UDTF

User Defined Table-Generating Functions

用户定义表生成函数,一行输入,多行输出

-- explode,炸裂函数
-- 就是将一行中复杂的 array 或者 map 结构拆分成多行 
select explode(array('A','B','C')) as col; 
select explode(map('a', 8, 'b', 88, 'c', 888));
-- UDTF's are not supported outside the SELECT clause, nor nested in expressions
-- SELECT pageid, explode(adid_list) AS myCol... is not supported
-- SELECT explode(explode(adid_list)) AS myCol... is not supported
-- lateral view 常与 表生成函数explode结合使用
 
-- lateral view 语法:
--Lateral View 用于和UDTF函数【explode,split】结合来使用。
--首先通过UDTF函数将数据拆分成多行,再将多行结果组合成一个支持别名的虚拟表。
--主要解决在select使用UDTF做查询的过程中查询只能包含单个UDTF,不能包含其它字段以及多个UDTF的情况。
lateralView: LATERAL VIEW udtf(expression) tableAlias AS columnAlias (',' columnAlias)*
fromClause: FROM baseTable (lateralView)*
 
-- lateral view 的基本使用
with t1 as (
  select 'OK' cola, split('www.lagou.com', '\\.') colb
)
select cola, colc from t1 lateral view explode(colb) t2 as colc;

窗口函数

窗口函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是:对于每个组返回多行,而聚合函数对于每个组只返回一行

over() 开窗

select sum(age) from tb1;

错误: select id,sum(age) as sum_age from tb1;

--窗口函数是针对每一行数据的,如果over中没有参数,默认的是全部结果集
select id,sum(age) over() as sum_age from tb1;

--在over窗口中进行分区,对某一列进行分区统计,窗口的大小就是分区的大小
select id,sum(age) over(partition by id) as sum_age from tb1;

-- order by
select id
    ,sum(age) over(partition by id order by age) as sum_age 
from tb1;

--Window子句 rows between ... and ...
select id
    ,sum(age) over(partition by id order by age 
    between 1 preceding and 1 following) as sum_age 
from tb1;

在这里插入图片描述

排名函数

row_number()。排名顺序增加不会重复;如1、2、3、4、… …

rank()。 排名相等会在名次中留下空位;如1、2、2、4、5、… …

dense_rank()。 排名相等会在名次中不会留下空位 ;如1、2、2、3、4、… …

select id,name,age
    ,row_number() over(partition by id order by age desc) as rank1
    ,rank() over(partition by id order by age desc) as rank2
    ,dense_rank() over(partition by id order by age desc) as rank3
from tb1;

序列函数

lag。返回当前数据行的上一行数据

lead。返回当前数据行的下一行数据

first_value。取分组内排序后,截止到当前行,第一个值

last_value。分组内排序后,截止到当前行,最后一个值

ntile。将分组的数据按照顺序切分成n片,返回当前切片值

select id, name, age,
       ntile(2) over(partition by id order by age) as ntile
from tb1;



with tmp as (
    select id, name, age,
       dense_rank() over (partition by id order by age desc) as rank
from tb1)
select id, score, rank,
       nvl(score - lag(score) over (partition by class order by score desc), 0) lagscore
  from tmp
 where rank<=3;      

with as

--WITH AS 语句可以为一个子查询语句块定义一个名称,功能类似临时表

-- with子句只能被select查询块引用
-- with子句的返回结果存到用户的临时表空间中,只做一次查询,反复使用,提高效率
-- 在同级select前有多个查询定义的时候,第1个用with,后面的不用with,并且用逗号隔开
-- 最后一个with 子句与下面的查询之间不能有逗号,只通过右括号分割,with 子句的查询必须用括号括起来

--相当于建了两个临时表a和b
with
a as (select * from tb1),
b as (select * from tb2)
select * from a, b where a.id = b.id;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值