show functions;
show functions like "*date*";
desc function 'current_date';
select current_date();
NVL:给值为NULL的数据赋值,它的格式是NVL( value,default_value)。它的功能是如果value为NULL,则NVL函数返回default_value的值,否则返回value的值,如果两个参数都为NULL,则返回NULL。
--查询员工表,将没有奖金的人的奖金列设置为-1
select comm,nvl(comm,-1) from emp;
数据
name | dept_id | sex |
---|---|---|
悟空 | A | 男 |
大海 | A | 男 |
宋宋 | B | 男 |
凤姐 | A | 女 |
王姐 | B | 女 |
婷婷 | B | 女 |
创建表,并加载数据
create table emp_sex(
name string,
dept_id string,
sex string)
row format delimited fields terminated by "\t";
load data local inpath '/opt/module/datas/emp_sex.txt' into table emp_sex;
查询不同部门各有多少人
select dept_id,count(*) total from emp_sex group by dept_id;
查询不同部门的男女各有多少人
select
dept_id,
count(*) total,
sum(case sex when '男' then 1 else 0 end) male,
sum(case sex when '女' then 1 else 0 end) female
from
emp_sex
group
by dept_id;
嵌套多个case when
select
dept_id,
count(*) total,
sum(case sex when '男' then 1 when '非男非女' then 0.5 else 0 end) male,
sum(case sex when '女' then 1 else 0 end) female
from
emp_sex
group
by dept_id;
concat(string A/col, string B/col…):将多列转化成一列,参数为列名,参数与参数之间可以添加分隔符;
concat_ws(separator, str1, str2,…):特殊形式的 CONCAT()。第一个参数为分隔符,后面可以传任意个参数或者是一个数组类型的集合,每个参数间以第一个参数为分隔规则输出出来;
collection_set(col):将一组的所有col按照数组输出出来,去重,结合group by使用;
collection_list(col):将一组的所有col按照数组输出出来,不去重,结合group by使用。
数据
name | constellation | blood_type |
---|---|---|
孙悟空 | 白羊座 | A |
唐僧 | 射手座 | A |
沙僧 | 白羊座 | B |
猪八戒 | 白羊座 | A |
林黛玉 | 射手座 | A |
武松 | 射手座 | A |
创建表导入数据
create table person_info(
name string,
constellation string,
blood_type string)
row format delimited fields terminated by "\t";
load data local inpath "/opt/module/datas/constellation.txt" into table person_info;
相同星座和血型的各有多少人
select
constellation,
blood_type,
count(*)
from
person_info
group by
constellation,
blood_type;
将星座和血型一样的人归类到一起
select
concat(constellation,",",blood_type) conblo,
concat_ws("|",collect_list(name)) name --拼接为字符串
from
person_info
group by
constellation,
blood_type;
explod(col):将hive一列中复杂的array或者map结构拆分成多行。
split(str, regex):将一个字符串按照regex规则切分为数组。
lateral view:用于和split, explode等UDTF一起使用,能够将一列数据拆成多行数据,在此基础上可以对拆分后的数据进行聚合。
用法:laterval view UDTF函数 表名 as 列名;
数据
movie | category |
---|---|
《疑犯追踪》 | 悬疑,动作,科幻,剧情 |
《Lie to me》 | 悬疑,警匪,动作,心理,剧情 |
《战狼2》 | 战争,动作,灾难 |
创建表导入数据
create table movie_info(
movie string,
category string)
row format delimited fields terminated by "\t";
load data local inpath "/opt/module/datas/movie.txt" into table movie_info;
split用法
select split(category,",") from movie_info;
将一行字符串拆分开,将一列扩展为一张表格
select explode(split(category,",")) from movie_info;
将category中的数据分开,并且前面显示电影名字
select
m.movie,
tbl.cate
from
movie_info m
lateral view
explode(split(category,",")) tbl as cate; --tbl为表名,cate为列名
拆分map集合,如果map集合不全,拆分后会补null
select
t.name,
tbl.cn,
tbl.age
from
test t
lateral view
explode(childten) tbl as cn,age;
列转行,行转列给我们提供了一个通过其他视角,或者通过其他聚合角度看数据的方式,
显示悬疑片有哪些,动作片有哪些等等()
--嵌套子查询
select
cate,
collect_list(movie)
from
(select
m.movie,
tbl.cate
from
movie_info m
lateral view
explode(split(category,",")) tbl as cate) t1
group by
cate;
--或者
select
tbl.cate,
collect_list(m.movie) --聚合电影名称
from
movie_info m
lateral view
explode(split(category,",")) tbl as cate
group by --以类别分组
cate;
将mysql复杂的查询封装成窗口的形式,使用方便,在统计中使用十分频繁。
over():指定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而变化。
current row:当前行
n preceding:往前n行数据
n following:往后n行数据
unbounded:起点,UNBOUNDED PRECEDING 表示从前面的起点, UNBOUNDED FOLLOWING表示到后面的终点
lag(col,n,default_val):往前第n行数据,对一个有序窗口使用,显示col列的上n行,没有前n行返回default_val
lead(col,n, default_val):往后第n行数据,对一个有序窗口使用
ntile(n):把有序窗口的行分发到指定数据的组中,各个组有编号,编号从1开始,对于每一行,NTILE返回此行所属的组的编号。注意:n必须为int类型,对一个有序窗口使用,平均分配。
创建表导入数据
create table business(
name string,
orderdate string,
cost int
) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
load data local inpath "/opt/module/datas/business.txt" into table business;
查询在2017年4月份购买过的顾客总人数
select
count(distinct name)
from
business
where
substring(orderdate,1,7)="2017-04";
将顾客姓名和顾客人数呈现在一张表上(每个人名后面都显示顾客人数)–窗口函数
窗口函数给聚合的函数提供了一个聚合的范围,之前通过group by指定,现在使用窗口函数
--加窗口函数指明count的对象,窗口函数中参数为空,表示对整张表的结果进行count
select
distinct name,
count(distinct name) over()
from
business
where
substring(orderdate,1,7)="2017-04";
查询所有顾客的购买明细和月购买总额
--按照orderdate的前7位分区并按照此分区进行加和
select
name,cost,orderdate,
sum(cost) over(partition by substring(orderdate,1,7))
from
business;
将每个顾客的cost按照日期进行累加
--按照姓名分区,区内按照日期升序排序,从每组第一行(unbounded preceding)到当前行进行加和
--排序再加和
select
name,cost,orderdate,
sum(cost) over(partition by name order by orderdate asc
rows between unbounded preceding and current row)
from
business;
--每个顾客每月的花费总额
select
name,cost,orderdate,
sum(cost) over(partition by name,substring(orderdate,1,7))
from
business;
--累加前一行,本行,后一行这三行的cost
--当没有前一行,加后一行和本行;没有后一行,加前一行和本行
select
name,cost,orderdate,
sum(cost) over(partition by name order by orderdate asc
rows between 1 preceding and 1 following)
from
business;
窗口函数执行顺序
from where group by select having over() order by limit
每个不同的窗口函数会启动一个MapReduce程序处理
select name,orderdate,cost,
sum(cost) over() as sample1,--所有行相加
sum(cost) over(partition by name) as sample2,--按name分组,组内数据相加
sum(cost) over(partition by name order by orderdate) as sample3,--按name分组,组内数据累加
sum(cost) over(partition by name order by orderdate rows between UNBOUNDED PRECEDING and current row ) as sample4 ,--和sample3一样,由起点到当前行的聚合
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 business;
--求各个月明细以及各个月有哪些顾客来过
select
name,orderdate,cost,
concat_ws(",",collect_set(name)
over(partition by substring(orderdate,1,7)))
from
business;
lead函数,over函数,查询每个顾客上次购买的时间
--结合其它函数使用
select
*,
lag(orderdate,1,"1970-01-01") --显示orderdate列前1行数据,如果没有返回“1970-01-01”
over(partition by name order by orderdate) last_order,
lead(orderdate,1,"1970-01-01")
over(partition by name order by orderdate) lead_order
from
business;
ntile函数,查询前20%时间的订单
select
*
from
(select
*,
ntile(5) over(order by orderdate) exam
from
business)exam1
where
exam=1;
percent_rank函数,查询前任意百分比的订单信息()
select
*
from
(select
*,
percent_rank() over (order by orderdate) pr
from
business) pr1
where
pr<0.08;
RANK() 排序相同时会存在并列情况,总数不会变
DENSE_RANK() 排序相同时会存在并列情况,总数会减少
ROW_NUMBER() 排序相同时不会存在并列情况,按照顺序排序
创建表导入数据
create table score(
name string,
subject string,
score int)
row format delimited fields terminated by "\t";
load data local inpath '/opt/module/datas/score.txt' into table score;
计算每门学科的排名
select
*,
rank() over(partition by subject order by score desc),
dense_rank() over(partition by subject order by score desc),
row_number() over(partition by subject order by score desc)
from
score;
查看当前日期
select current_date();
日期的加减
--查看从今天开始之后的第90天后的时间
select date_add(current_date(),90);
--查看从今天开始之前的第90天后的时间
select date_sub(current_date(),90);
两个日期间的差值
select datediff(current_date,'1990-01-01');
hive配套数据