2015-05-19 3 views
0

У меня есть таблица вроде этого:Как я могу получить данные группы и собирать результат на карте в Hive?

id | job  | school | 
1 | programmer | school1 | 
2 | programmer | school1 | 
3 | programmer | school2 | 
4 |  pm  | school3 | 
5 |  pm  | school2 | 
6 |  pm  | school3 | 

Я хочу сделать следующее:

  1. Группа по работе
  2. Получить список школ и подсчитывать, как это [(school1, 2), (school2, 1)] список
  3. школа порядок по количеству, так что не может быть [(school1, 1), (school1, 2)]

Результат примера:

programmer | [(school1, 2), (school2, 1)] 
    pm  | [(school3, 2), (school2, 1)] 

ответ

1

Просто добавьте Brickhouse банки и создать collect() функция

add jar ./brickhouse-0.7.1.jar; 
create temporary function collect as 'brickhouse.udf.collect.CollectUDAF'; 

select job 
    , collect(school, c) school_count_map 
from (
    select * 
    from (
    select job, school 
     , count(*) c 
    from table 
    group by job, school) x 
    order by job, c desc) y 
group by job 
1

Мы не можем иметь карту внутри коллекции (collect_set) в улье (Коз только примитивные типы данных разрешены внутри collect_set).

Этих 2 запросов будет давать то, что вы ищете (оба такие же, за исключением, что одна карты включает в себя другие не)

CREATE EXTERNAL TABLE job_test(
    id string, 
    job string, 
    school string) 
ROW FORMAT DELIMITED 
FIELDS TERMINATED BY ',' 
LINES TERMINATED BY '\n' 
STORED AS TEXTFILE 
LOCATION '/user/test/job.txt'; 

SELECT b.job, collect_set(concat_ws(':',map_keys(b.school_map),map_values(b.school_map))) as school_cnt 
FROM 
(
    SELECT a.job, map(a.school,a.cnt) as school_map 
    FROM 
    ( 
     SELECT job, 
       school, 
       cast(count(1) as string) as cnt 
     FROM job_test 
     GROUP BY 
       job, 
       school 
    )a 
)b 
GROUP BY b.job; 

SELECT a.job, collect_set(concat_ws(':',a.school,a.cnt)) as school_cnt 
FROM 
(
    SELECT job, 
      school, 
      cast(count(1) as string) as cnt 
    FROM job_test 
    GROUP BY 
      job, 
      school 
)a 
GROUP BY a.job; 

Надеется, что это помогает :)

+0

но не сортировать collect_set – roger

+0

хмм .. выход уже отсортированных по столбцам работы .. –