2014-10-16 3 views
3

У меня есть 2 таблицы в улье, у которых есть Order и Order_Detail (с отношением 1: n и соединенным на order_id), который я пытаюсь загрузить в один таблица, использующая тип данных типа hive - map [struct].Как загрузить таблицу улья с картой [structs] из другого плоского/простого таблицы улья

Скажем порядка имеет ниже данных,

ORDER_ID TOTAL_AMOUNT клиентов

123 10,00 1

456 12,00 2

и order_details имеют

ORDER_ID Order_Item_id Item_amount item_type

123 1 5.00

123 2 5,00 Б

456 1 6,00

456 2 3,00 Б

456 3 3.00 С

Я хотел бы создать одну таблицу заказов с все столбцы заказа и столбцы order_detail в качестве карты структур. Это помогает мне комбинировать связанные данные и запросы вместе, тем самым избегая частых объединений. Я попытался загрузить таблицу со сложными типами данных, используя входные файлы txt/json с соответствующими serde's, и он работает хорошо. Но в этом сценарии я хочу загрузить данные из существующих 2 таблиц верстки формата ORCFile в новую таблицу. Попробовали некоторую базовую вставку с использованием функции named_struct, но она загружает каждую строку отдельно и не объединяет одинаковые order_id в одну строку.

Ожидаемые результаты что-то вроде

123 10,00 1 [1: {5.00, А}, 2: {5.00, B}]

456 12,00 2 {1: {6.00, А}, 2 : {3.00, B}, 3: {3.00, С}]

но я получаю,

123 10,00 1 [1: {5.00, а}]

123 10,00 1 [2: { 5,00, B}]

456 12,00 2 {1: {6.00, А}]

456 12,00 2 {2: {3.00, B}]

456 12,00 2 {3: {3.00, С}]

Пожалуйста, помогите мне понять способ достижения этого, используя только таблицу INSERT INTO из 2 таблиц. Спасибо заранее.

ответ

3

Я нашел способ сделать это с помощью функций map, named_struct и пользовательского UDF to_map, размещенного David Worms по адресу to_map UDF blog. Вот пример,

CREATE TABLE ORDER(
 
    order_id bigint, 
 
    total_amount bigint, 
 
    customer bigint) 
 
ROW FORMAT DELIMITED 
 
FIELDS TERMINATED BY ',' 
 
STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat' 
 
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'; 
 

 
CREATE TABLE ORDER_DETAILS(
 
    order_id bigint, 
 
    Order_Item_id bigint, 
 
    Item_amount bigint, 
 
    Item_type string) 
 
ROW FORMAT DELIMITED 
 
FIELDS TERMINATED BY ',' 
 
STORED AS INPUTFORMAT 
 
    'org.apache.hadoop.mapred.TextInputFormat' 
 
OUTPUTFORMAT 
 
    'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'; 
 

 
CREATE TABLE ORDERS(
 
    order_id bigint, 
 
    Order_Items map < bigint, struct < Item_amount: bigint, Item_type: string >> , 
 
    total_amount bigint, 
 
    customer bigint) 
 
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.orc.OrcSerde' 
 
STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.orc.OrcInputFormat' 
 
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat'; 
 

 
Insert overwrite table ORDERS 
 
select 
 
a.order_id, 
 
    a.order_items, 
 
    b.total_amount, 
 
    b.customer 
 
from 
 
    (select order_id as order_id, 
 
    to_map(order_item_id, named_struct("item_amount", item_amount, "item_type", item_type)) as order_items from ORDER_DETAILS group by order_id) a 
 
JOIN ORDER b ON(a.order_id = b.order_id);

выберите * от ЗАКАЗОВ;

123 {1: { "Item_amount": 5, "item_type": "А"}, 2: { "Item_amount": 5, "item_type": "В"}} 10 1

456 { 1: { "Item_amount": 6, "item_type": "А"}, 2: { "Item_amount": 3, "item_type": "В"}, 3: { "Item_amount": 3, "item_type":» C "}} 12 2

Надеюсь, это поможет всем.

+0

Спасибо, что поделились своим решением, @ Kunal. Это помогло мне решить аналогичный вариант использования. – activelearner

Смежные вопросы