如何有效地取消配置单元中多个列的拆分?

iq3niunx  于 2021-06-27  发布在  Hive
关注(0)|答案(3)|浏览(207)

我的数据结构如下表所示:

| Name | Foo_A | Foo_B | Foo_C | Bar_A | Bar_B | Bar_C |
--------------------------------------------------------
| abcd |    16 |    32 |    14 |    52 |    41 |    17 |
| ...  |   ... |   ... |   ... |   ... |   ... |   ... |

我希望以如下方式查询配置单元中的数据:

| Name | Class | FooVal | BarVal |
----------------------------------
| abcd | A     |     16 |     52 |
| abcd | B     |     32 |     41 |
| abcd | C     |     14 |     17 |
| ...  | ...   |    ... |    ... |

我已经意识到并正在使用一个union all,但是使用“横向视图分解”Map数据类型有什么更有效的方法呢?

xwbd5t1u

xwbd5t1u1#

交叉连接
class stack (参见代码示例)将主表行x3相乘,每行一行 class ,然后使用 case 派生列所依赖的语句 class 价值观。带有小数据集(3行)的交叉连接应转换为Map连接,并在Map程序上执行得非常快。

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方法的性能要好得多。

7vux5j2d

7vux5j2d2#

配置单元取消拆分多个列:

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
3lxsmp7m

3lxsmp7m3#

谢谢回复!请在下面找到另一种比交叉连接更快的方法。

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;

相关问题