Hive 行转列,列转行,窗口函数,窗口排序函数

1. 行转列

collect_set() / collect_list()、concat_ws()

1.1 collect_set() collect_list()

collect_set() 函数只接受基本数据类型,作用是对参数字段进行去重汇总,返回array类型字段;
collect_list() 函数和collect_set()作用一样,只是前者不去重,后者去重。

1.2 concat_ws()

concat_ws (separator,字符串A/字段名A,字符串B/字段名B…)是concat的特殊形式,第一个参数是分隔符,分隔符会放到要连接的字符串之间,分隔符可以是字符串,也可以是其他参数。如果分隔符为NULL,则结果为NULL,函数会忽略任何分隔符参数后的 NULL值。但是concat_ws( )不会忽略任何空字符串。(然而会忽略所有的 NULL),如果参数为string类型数组则合并数组内字符串。

/* 原始数据
name       gender          times
张三         男            唐
李四         男            唐
王五         男            明
赵六         男            明
*/
-- 先用collect_set将列拼接在一起,然后再通过concat_ws进行展开拼接
SELECT a.gender_times,
       concat_ws(';',collect_set(a.name)) name
FROM
  (SELECT name,
          concat(gender, '_','times') gender_times
   FROM hero_info) t
GROUP BY t.gender_times;
/*查询结果
gender_times    name    
男_唐     张三;李四

2. 列转行

关键字:explode()、split()和LATERAL VIEW

2.1 split()

将一个字符串按照指定字符分割,结果为一个array;

2.3 explode()

将一列复杂的array或者map拆分为多行,它的参数必须为map或array;

2.4 lateral view

lateral view udtf(字段名)表别名/表临时名as列别名/列临时名。lateral view用于和split, explode等UDTF一起使用,它能够将一行数据拆成多行数据,在此基础上可以对拆分后的数据进行聚合。lateral view首先为原始表的每行调用UDTF,UTDF会把一行拆分成一或者多行,lateralview再把结果组合,产生一个支持别名表的虚拟表。

2.5 列转行基本语法

select  字段,字段别名  from table_name lateral view explode(split(拆分字段,分隔符))表别名 as 字段别名;

/*原始数据
province       city
河南           郑州市,开封市,洛阳市
河北           石家庄市,保定市
湖南           长沙市,岳阳市,常德市
*/
-- addr为表名
SELECT province,
       city_n
FROM addr LATERAL VIEW explode (split(city,',')) addr_tmp AS city_n;
/*
-- 查询结果
河南      郑州市
河南      开封市
河南      洛阳市
河北      石家庄市
河北      保定市
湖南      长沙市
湖南      岳阳市
湖南      常德市

3. 窗口排序函数

RANK() 排序相同时会重复,总数不会变

DENSE_RANK() 排序相同时会重复,总数会减少

ROW_NUMBER() 会根据顺序计算

1,计算没门科目的成绩排名:
 
[isea@hadoop108 datas]$ cat score.txt 
悟空		语文		87
悟空		数学		95
悟空		英语		68
八戒		语文		94
八戒		数学		56
八戒		英语		84
张飞		语文		64
张飞		数学		86
张飞		英语		84
小乔		语文		65
小乔		数学		85
小乔		英语		78
 
创建hive表,并导入数据:
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 * from score;
 
+-------------+----------------+--------------+--+
| score.name  | score.subject  | score.score  |
+-------------+----------------+--------------+--+
| 悟空          | 语文             | 87           |
| 悟空          | 数学             | 95           |
| 悟空          | 英语             | 68           |
| 八戒          | 语文             | 94           |
| 八戒          | 数学             | 56           |
| 八戒          | 英语             | 84           |
| 张飞          | 语文             | 64           |
| 张飞          | 数学             | 86           |
| 张飞          | 英语             | 84           |
| 小乔          | 语文             | 65           |
| 小乔          | 数学             | 85           |
| 小乔          | 英语             | 78           |
+-------------+----------------+--------------+--+
 
 
计算每门科目的成绩排名:每门科目,表示要对科目进行分组,排名所以要排序。这里面的rank只是打标记而已
 
select *,rank() over(partition by subject order by score desc) rank,
dense_rank() over(partition by subject order by score desc) dense_rank,
row_number() over(partition by subject order by score desc) row_number
from score;
 
+-------------+----------------+--------------+-------+-------------+-------------+--+
| score.name  | score.subject  | score.score  | rank  | dense_rank  | row_number  |
+-------------+----------------+--------------+-------+-------------+-------------+--+
| 悟空          | 数学             | 95           | 1     | 1           | 1           |
| 张飞          | 数学             | 86           | 2     | 2           | 2           |
| 小乔          | 数学             | 85           | 3     | 3           | 3           |
| 八戒          | 数学             | 56           | 4     | 4           | 4           |
| 张飞          | 英语             | 84           | 1     | 1           | 1           |
| 八戒          | 英语             | 84           | 1     | 1           | 2           |
| 小乔          | 英语             | 78           | 3     | 2           | 3           |
| 悟空          | 英语             | 68           | 4     | 3           | 4           |
| 八戒          | 语文             | 94           | 1     | 1           | 1           |
| 悟空          | 语文             | 87           | 2     | 2           | 2           |
| 小乔          | 语文             | 65           | 3     | 3           | 3           |
| 张飞          | 语文             | 64           | 4     | 4           | 4           |
+-------------+----------------+--------------+-------+-------------+-------------+--+
 
2,求出每门学科前三名的学生?
 
t1:
select *,row_number() over(partition by subject order by score desc) row_number
from score;
 
select * from
(
select *,row_number() over(partition by subject order by score desc) row_number
from score)t1
where t1.row_number <= 3;
 
+----------+-------------+-----------+----------------+--+
| t1.name  | t1.subject  | t1.score  | t1.row_number  |
+----------+-------------+-----------+----------------+--+
| 悟空       | 数学          | 95        | 1              |
| 张飞       | 数学          | 86        | 2              |
| 小乔       | 数学          | 85        | 3              |
| 张飞       | 英语          | 84        | 1              |
| 八戒       | 英语          | 84        | 2              |
| 小乔       | 英语          | 78        | 3              |
| 八戒       | 语文          | 94        | 1              |
| 悟空       | 语文          | 87        | 2              |
| 小乔       | 语文          | 65        | 3              |
+----------+-------------+-----------+----------------+--+

猜你喜欢

转载自blog.csdn.net/weixin_44402973/article/details/126276439