阿里交叉面试问到了这个题,当时感觉没有答好,主要是对Hive这块还是不熟悉,其实可以采用row_number()函数。

1、ROW_NUMBER,RANK(),DENSE_RANK()

语法格式:row_number() OVER (partition by COL1 order by COL2 desc ) rank
partition by:类似hive的建表,分区的意思;
order by :排序,默认是升序,加desc降序;
rank:表示别名
表示根据COL1分组,在分组内部根据 COL2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的)

1.1 案例

1.1.1 样本数据

浙江,杭州,300
浙江,宁波,150
浙江,温州,200
浙江,嘉兴,100
江苏,南京,270
江苏,苏州,299
江苏,某市,200
江苏,某某市,100

1.1.2导入数据

--执行下述语句
hive (temp)> hive -f 'HQL/loaddata.hql'>out/tmp;
-----------------------------------------------
drop table datatable;
CREATE table datatable (
province string,
city string,
people int)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS TEXTFILE; load data local inpath 'home/loaddata'
overwrite into table temp.datatable;
----------------------------------------------
--查看结果
hive (temp)> select * from datatable;
OK
province city people
浙江 杭州 300
浙江 宁波 150
浙江 温州 200
浙江 嘉兴 100
江苏 南京 270
江苏 苏州 299
江苏 某市 200
江苏 某某市 100

1.2 按照人口降序排列,生成衍生变量

select province,city,
rank() over (order by people desc) rank,
dense_rank() over (order by people desc) dense_rank,
row_number() over(order by people desc) row_number
from datatable
group by province,city,people; --结果
province city rank dense_rank row_number
浙江 杭州 1 1 1
江苏 苏州 2 2 2
江苏 南京 3 3 3
浙江 温州 4 4 4
江苏 某市 4 4 5
浙江 宁波 6 5 6
江苏 某某市 7 6 7
浙江 嘉兴 7 6 8

主要注意打圈的:
row_number:顺序下来
rank:在遇到数据相同项时,会留下空位5,(第一列4,4,6)
dense_rank:在遇到数据相同项时,不会留下空位,(红框内第一列,4,4,5)

1.3 分组按照省份分区,再按照人口降序排列,生成衍生变量

select province,city,
rank() over (partition by province order by people desc) rank,
dense_rank() over (partition by province order by people desc) dense_rank,
row_number() over(partition by province order by people desc) row_number
from datatable
group by province,city,people; --结果
province city rank dense_rank row_number
江苏 苏州 1 1 1
江苏 南京 2 2 2
江苏 某市 3 3 3
江苏 某某市 4 4 4
浙江 杭州 1 1 1
浙江 温州 2 2 2
浙江 宁波 3 3 3
浙江 嘉兴 4 4 4

2取TOPN数据

2.1 按照国家提取TOP3

2.1.1 样本数据:

国家 城市 Visitors
阿联酋,阿布扎比,137
阿联酋,阿布扎比,146
阿联酋,阿布扎比,178
阿联酋,阿布扎比,337
阿联酋,阿布扎比,178
阿联酋,阿布扎比,227
阿联酋,阿布扎比,157
阿联酋,迪拜,144
阿联酋,迪拜,268
阿联酋,迪拜,103
阿联酋,迪拜,141
阿联酋,迪拜,108
阿联酋,迪拜,266
澳大利亚,悉尼,141
澳大利亚,悉尼,122
澳大利亚,悉尼,153
澳大利亚,悉尼,128
澳大利亚,墨尔本,294
澳大利亚,墨尔本,230
澳大利亚,墨尔本,159
澳大利亚,墨尔本,188
澳大利亚,堪培拉,249
澳大利亚,堪培拉,378
澳大利亚,堪培拉,255
澳大利亚,堪培拉,240

2.1.2导入数据

--执行下述语句
hive (temp)> hive -f 'HQL/loaddata.hql'>out/tmp;
-----------------------------------------------
drop table temp.tripdata;
CREATE table datatable (
country string,
city string,
Visitors int)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS TEXTFILE; load data local inpath 'home/loaddata'
overwrite into table temp.tripdata;
---------------------------------------------- ----------------------------------------------
--查看结果
hive (temp)> select * from tripdata;
country city visitors
阿联酋 阿布扎比 137
阿联酋 阿布扎比 146
阿联酋 阿布扎比 178
阿联酋 阿布扎比 337
阿联酋 阿布扎比 178
阿联酋 阿布扎比 227
阿联酋 阿布扎比 157
阿联酋 迪拜 144
阿联酋 迪拜 268
阿联酋 迪拜 103
阿联酋 迪拜 141
阿联酋 迪拜 108
阿联酋 迪拜 266
澳大利亚 悉尼 141
澳大利亚 悉尼 122
澳大利亚 悉尼 153
澳大利亚 悉尼 128
澳大利亚 墨尔本 294
澳大利亚 墨尔本 230
澳大利亚 墨尔本 159
澳大利亚 墨尔本 188
澳大利亚 堪培拉 249
澳大利亚 堪培拉 378
澳大利亚 堪培拉 255
澳大利亚 堪培拉 240
---格式:select 品牌,count/sum/其它() as num from table_name order by num limit 10; select country,city,visitors
from tripdata
order by visitors desc
limit 5; country city visitors
澳大利亚 堪培拉 378
阿联酋 阿布扎比 337
澳大利亚 墨尔本 294
阿联酋 迪拜 268
阿联酋 迪拜 266

2.2 按照国家、城市提取TOP3

--取top10品牌下各品牌的top10渠道 ,格式:
select
a.*
from
(
select 品牌,渠道,count/sum/其它() as num row_number() over (partition by 品牌 order by num desc ) rank
from table_name
where 品牌限制条件
group by 品牌,渠道
)a
where a.rank<=10
select a.*
from (
select country,city,visitors, row_number() over (partition by country order by visitors desc ) rank
from tripdata
order by country,visitors desc
) a
where a.rank<=3; --结果
a.country a.city a.visitors a.rank
澳大利亚 堪培拉 378 1
澳大利亚 墨尔本 294 2
澳大利亚 堪培拉 255 3
阿联酋 阿布扎比 337 1
阿联酋 迪拜 268 2
阿联酋 迪拜 266 3

2.3 按照国家提取TOP5

--取top10品牌下各品牌的top10渠道中各渠道的top10档期 ,格式:
select a.*
from
(
select 品牌,渠道,档期,count/sum/其它() as num row_number() over (partition by 品牌,渠道 order by num desc ) rank
from table_name
where 品牌,渠道 限制条件
group by 品牌,渠道,档期
)a
where a.rank<=10
select a.*
from (
select country,city,visitors, row_number() over (partition by city order by visitors desc ) rank
from tripdata
order by country,city,visitors desc
) a
where a.rank<=3; --结果
a.country a.city a.visitors a.rank
澳大利亚 堪培拉 378 1
澳大利亚 堪培拉 255 2
澳大利亚 堪培拉 249 3
澳大利亚 墨尔本 294 1
澳大利亚 墨尔本 230 2
澳大利亚 墨尔本 188 3
澳大利亚 悉尼 153 1
澳大利亚 悉尼 141 2
澳大利亚 悉尼 128 3
阿联酋 迪拜 268 1
阿联酋 迪拜 266 2
阿联酋 迪拜 144 3
阿联酋 阿布扎比 337 1
阿联酋 阿布扎比 227 2
阿联酋 阿布扎比 178 3

链接:https://www.jianshu.com/p/9802f3a035e1

Hive分组取Top K数据的更多相关文章

  1. Hive分组取Top N

    Hive在0.11.0版本开始加入了row_number.rank.dense_rank分析函数,可以查询分组排序后的top值   说明: row_number() over ([partition ...

  2. sql 分组取最新的数据sqlserver巧用row_number和partition by分组取top数据

    SQL Server 2005后之后,引入了row_number()函数,row_number()函数的分组排序功能使这种操作变得非常简单 分组取TOP数据是T-SQL中的常用查询, 如学生信息管理系 ...

  3. row_number和partition by分组取top数据

    分组取TOP数据是T-SQL中的常用查询, 如学生信息管理系统中取出每个学科前3名的学生.这种查询在SQL Server 2005之前,写起来很繁琐,需要用到临时表关联查询才能取到.SQL Serve ...

  4. Spark 两种方法计算分组取Top N

    Spark 分组取Top N运算 大数据处理中,对数据分组后,取TopN是非常常见的运算. 下面我们以一个例子来展示spark如何进行分组取Top的运算. 1.RDD方法分组取TopN from py ...

  5. sql分组取第一条数据

    sq分组取第一条数据的一个方法: select * from ( select row_number() over(partition by ID order by ID) as rownum , * ...

  6. oracle 分组取第一行数据 ,查询sql语句

    oracle  分组取第一行数据 SELECT * FROM ( SELECT ROW_NUMBER() OVER(PARTITION BY x ORDER BY y DESC) rn, t.* FR ...

  7. Hive分组取第一条记录

    需求 交易系统,财务要求维护每个用户首个交易完成的订单数据(首单表,可取每个用户交易完成时间最老的订单数据).举例: 简写版的表结构: 表数据: 则 财务希望汇总记录如下: uid order_id ...

  8. oracle 根据字段分组取第一条数据及rank函数说明

    当前有这样一个需求,根据外键对子表数据进行分组,取每组中的一条数据就行了,如图: 如:COMMANDID = 26的有两条,只取一条数据. sql语句: select * from(select SY ...

  9. c# 对List<T> 某字段排序,取TOP条数据

    //排序的对象里的字段数据准备 try { cmr.v4 = Double.Parse(cmr.v3) - Double.Parse(cmr.v2); } catch (Exception e) { ...

随机推荐

  1. VB通用数据库操作方法

    1.VB通用数据操作方法. 2.通用数据库查询方法. 3.通用数据库操作方法. 'ERP查询数据库 Public Function YZQuery(sqls As String, msgstring ...

  2. grafana 的面板设置

    1.工作中我们会计算连个字段的四则运算

  3. 使用Vuex打开log功能

    vuex是一个比较好用的数据流管理库,可以用统一的流程来处理状态数据,但是,也正是因为这些流程,我们需要打一些log来观察流程是否会出现问题,具体方法如下: import Vue from 'vue' ...

  4. 打造 Vue.js 可复用组件

    Vue.js 是一套构建用户界面的渐进式框架.我们可以使用简单的 API 来实现响应式的数据绑定和组合的视图组件. 从维护视图到维护数据,Vue.js 让我们快速地开发应用.但随着业务代码日益庞大,组 ...

  5. 转:\r,\n,\r\n的区别

    回车.换行的区别   他们间的区别其实是个回车换行的问题 先来段历史 回车”(Carriage Return)和“换行”(Line Feed)这两个概念的来历和区别. 符号        ASCII码 ...

  6. lua -- 事件响应与局部变量

    -- 这里要注意的点是:虽然nAmount是局部变量,却在控件的响应函数中使用 -- 因为控件的响应函数是在该变量的区域内,所以可以用 -- 如果控件的响应函数在外部,那么该变量就要声明成为全局变量 ...

  7. transfer learning

    https://github.com/jindongwang/transferlearning ftp://ftp.cs.wisc.edu/machine-learning/shavlik-group ...

  8. 如何在 Linux 上设置密码策略

    https://linux.cn/article-2518-1.html 用户帐号管理是系统管理员最重要的工作之一.而密码安全是系统安全中最受关注的一块.在本教程中,我将为大家介绍如何在 Linux ...

  9. 【Acm】算法之美—Anagrams by Stack

    题目概述:Anagrams by Stack How can anagrams result from sequences of stack operations? There are two seq ...

  10. vim复制内容到系统剪贴板

    vim提供了y键盘操作用于复制文本,但是复制之后的文本位于当前窗口的缓冲区中,不在系统剪贴板中,这给跨程序文本拷贝代码很来很多麻烦.搜索发现,可以使用]y指令快速将选定的文本复制到系统剪贴板中. 顺便 ...