我的数据的结构如下表所示:
| Name | Foo_A | Foo_B | Foo_C | Bar_A | Bar_B | Bar_C |
--------------------------------------------------------
| abcd | 16 | 32 | 14 | 52 | 41 | 17 |
| ... | ... | ... | ... | ... | ... | ... |
我希望以类似以下方式查询Hive中的数据:
| Name | Class | FooVal | BarVal |
----------------------------------
| abcd | A | 16 | 52 |
| abcd | B | 32 | 41 |
| abcd | C | 14 | 17 |
| ... | ... | ... | ... |
我已经知道并正在使用UNION ALL,但是使用“横向视图爆炸”地图数据类型可以更有效地实现此目的?
答案 0 :(得分:0)
使用class
stack
进行交叉联接(请参见代码示例)将主表行x3乘以每class
的一行,然后使用case
语句来派生列,具体取决于class
值。具有小数据集(3行)的CROSS JOIN应该转换为 map join ,并且将在映射器上非常快速地执行。
set hive.auto.convert.join=true; --this enables map-join
select t.Name,
s.class,
case s.class when 'A' then t.Foo_A
when 'B' then t.foo_B
when 'C' then t.foo_C
end as FooVal,
case s.class when 'A' then t.Bar_A
when 'B' then t.Bar_B
when 'C' then t.Bar_C
end as BarVal
from table t
cross join (select stack(3,'A','B','C') as class) s
;
它只会扫描表一次,并且比UNION ALL方法的性能要好得多。
答案 1 :(得分:0)
感谢您的回复!请在下面找到比CROSS JOIN更快的另一种方式。
select t1.ID, t2.key_1 as class, t2.FooVal, t3.BarVal
from table t1
LATERAL VIEW explode (map(
'A', Foo_A,
'B', Foo_B,
'C', Foo_C
)) t2 as key_1, FooVal
LATERAL VIEW explode (map(
'A', Bar_A,
'B', Bar_B,
'C', Bar_C
)) t3 as key_2, BarVal
where t2.key_1 = t3.key_2;
答案 2 :(得分:0)
配置单元取消多列显示:
select
t1.ID,
lv.key as class,
lv.FooStr.col1 as FooVal,
lv.FooStr.col2 as BarVal
from
table t1
LATERAL VIEW explode (
map(
'A', named_struct('col1', Foo_A, 'col2', Bar_A),
'B', named_struct('col1', Foo_B, 'col2', Bar_B),
'C', named_struct('col1', Foo_C, 'col2', Bar_C)
)) lv as key, FooStr
where
coalesce(lv.FooStr.col1, lv.FooStr.col2) IS NOT NULL