如何汇总基于列的多个条件以获得更好的性能?

时间:2018-09-20 00:32:22

标签: sql hive

我有一个十亿行表,其数据格式为-

id  col1 col2
1   100  21
1   110  22
1   120  21
1   20   35
2   230  22
2   2    22
3   456  31
3   30   21
3   2    31
4   200  33
5   45   34

我需要根据col2上的各种条件找到col1的最小值和最大值,并获取结果表。目前,我正在使用左连接表本身,但这效率不高,并且花费了70分钟以上。

我现在正在运行的示例查询看起来像这样-

select distinct t.id, t1.m1 colA,t2.m2 colB,t3.m3 colC
from table1 t
left join (select id,min(col1) over (partition by id) m1  from table1 where col2=21) t1 on (t.id=t1.id)  
left join (select id,min(col1) over (partition by id) m2 from table1 where col2 in (22,23,34) ) t2 on (t.id=t2.id) 
left join (select id,max(col1) over (partition by id) m3 from table1 id where col2 in (21,33,22,35) )t3 on (t.id=t3.id)

hive 1.2 中,是否有更好的方法可以更有效地达到相同的结果?

上述查询的结果是:

id  colA    colB   colC 
1   100     110    120
2   NULL    2      230
3   30      NULL   30
4   NULL    NULL   200
5   NULL    45     NULL

PS:Col1实际上是一个时间戳

1 个答案:

答案 0 :(得分:2)

我建议使用“条件聚合”,这基本上意味着将一个case表达式放在聚合函数中:

select
      t.id
    , max(case when col2=21 then t.col1 end)              colA
    , min(case when col2 in (22,23,34) then t.col1 end)   colB
    , max(case when col2 in (21,33,22,35 then t.col1 end) colC
from table1 t
group by t.id

这应减少通过源表传递多个左联接的次数。

还请注意,尽管“选择不同”可能会产生所需的结果,但这是“昂贵”的选择。 GROUP BY不仅可以产生唯一的行,而且还可以同时进行汇总。