Как я могу получить групповые данные и собрать результат в карту в 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)]

2 ответа

Решение

Просто добавьте кувшин 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

У нас не может быть Карты внутри Коллекции (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;

Надеюсь это поможет:)

Другие вопросы по тегам