Hive 그룹 에서 Top N 데이터 가 져 오기
27098 단어 빅 데이터 ~ Hive
문법: rownumber () OVER (partition by COL 1 order by COL 2 desc) rankpartition by: hive 와 같은 건축 표, 분 구 의 뜻;order by: 정렬, 기본 값 은 오름차 순, desc 내림차 순 추가;rank: 별명 은 COL 1 에 따라 그룹 을 나 누고 그룹 내부 에서 COL 2 에 따라 정렬 하 는 것 을 나타 내 며 이 함수 가 계산 한 값 은 각 그룹 내부 에서 정렬 한 순서 번호 (그룹 내 연속 유일한 것) 를 나타 낸다.
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, 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 국가 별 TOP 3 추출
2.1.1 견본 데이터:
UAE, 아랍 에 미 리 트, 아부 다비, 137 UAE, 아랍 에 미 리 트, 아랍 에 미 리 트, 아랍 에 미 리 트, 아랍 에 미 리 트, 아랍 에 미 리 트, 아랍 에 미 리 트, 아랍 에 미 리 트, 아랍 에 미 리 트, 337 UAE, 아랍 에 미 리 트, 아랍 에 미 리 트, 178 UAE, 아랍 에 미 리 트, 227 UAE, 아랍 에 미 리 트, 아랍 에 미 리 트, 두 바 이, 두 바 이, 두 바 이, 268 아랍 에 미 리 트, 두 바 이, 268 아랍 에 미 리 트, 두 바 이, 268 UAE, 두 바 이, 103 아랍 에 미 리 트, 두 바 이, 두 바 이, 두 바 이, 두 바 이, 두 바 이, 두 바 이, UAE, 두 바 이, 두 바 이, 두 바 이, 268 UAE, 두 바 이, 시드니호주, 시드니, 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 국가, 도시 별 TOP 3 추출
-- 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 국가 별 TOP 5 추출
-- 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
===============================================================
Hive 는 0.11.0 버 전부터 row number, rank, dense rank 분석 함 수 를 추가 하여 그룹 정렬 후의 top 값 을 조회 할 수 있 습 니 다.
설명:
row_number() over ([partition col1] [order by col2])
rank() over ([partition col1] [order by col2])
dense_rank() over ([partition col1] [order by col2])
이들 은 모두 col 1 필드 에 따라 그룹 을 나 눈 다음 col 2 필드 를 정렬 하여 정렬 한 줄 마다 줄 번 호 를 만 듭 니 다. 이 줄 번 호 는 1 부터 점점 증가 합 니 다.
col 1, col 2 는 여러 필드 로 구분 할 수 있 습 니 다.
구별:
1)row_number: col 2 필드 의 값 이 같 든 안 같 든 줄 번호 가 계속 증가 합 니 다. 예 를 들 어 두 개의 기록 값 이 같 지만 하 나 는 첫 번 째 이 고 하 나 는 두 번 째 입 니 다.
2) rank: 상하 두 개의 기 록 된 col 2 가 같 을 때 기 록 된 줄 번 호 는 같 지만 다음 col 2 값 의 줄 번 호 는 N (N 은 중복 되 는 횟수) 으로 증가 합 니 다. 예 를 들 어 두 개의 공동 1 위 가 있 고 다음 은 3 위 이 며 두 번 째 가 없습니다.
3)dense_rank: 상하 두 개의 기 록 된 col 2 가 같 을 때 다음 col 2 값 의 줄 번호 가 1 증가 합 니 다. 예 를 들 어 두 개의 공동 1 위 가 있 고 다음 은 두 번 째 입 니 다.
row_number 는 페이지 별 조 회 를 실현 할 수 있다.
실례:
hive> create table t(name string, sub string, score int) row format delimited fields terminated by '\t';
데 이 터 는 첨부 된 a. txt 에 있 습 니 다.
a chinese 98
a english 90
d chinese 88
c english 82
c math 98
b math 89
b chinese 79
z english 90
z math 89
z chinese 80
e math 99
e english 87
d english 90
1、row_number
hive (test)> select *, row_number() over (partition by sub order by score) as od from t;
2、rank
hive (test)> select *, rank() over (partition by sub order by score) as od from t;
3、dense_ran
hive (test)> select *, dense_rank() over (partition by sub order by score desc) from t;
비 즈 니스 인 스 턴 스:
각 학과 의 3 등 을 통계 하 다.
select * from (select *, row_number() over (partition by sub order by score desc) as od from t ) t where od<=3;
국어 성적 이 80 점 인 데 순위 가 어떻게 돼 요?
hive (test)> select od from (select *, row_number() over (partition by sub order by score desc) as od from t ) t where sub='chinese' and score=80;
페이지 별 조회
hive (test)> select * from (select *, row_number() over () as rn from t) t1 where rn between 1 and 5;