Apache Hive不同的查询联合,在同一个表上,每个查询中的where条件不同?

时间:2014-09-16 11:32:35

标签: hadoop hive union hdfs

我有一个名为“sales”的Hive表,结构如下:

id,ptype,amount,time,date
1,a,12,2240,2013-12-25
1,a,4,1830,2013-12-25
1,b,2,1920,2013-12-25
1,b,3,2023,2013-12-25
2,a,5,1220,2013-12-25
2,a,1,1320,2013-12-25

以下是我对不同变量变量的查询:

Q1: select id,sum(amount) as s_amt from sales group by id;
Q2: select id, sum(amount) as s_a_amt from sales where ptype='a' group by id;
Q3: select id, sum(amount) as s_b_amt from sales where ptype='b' group by id;

就我在Hive中学到的东西而言,只有当我们有相同的列名或查询模式时,我们才能应用“union all”选项。以下是我想要使用Hive查询实现的最终结果:

id,s_amt,s_a_amt,s_b_amt
1,21,16,5
2,6,6,0

以下是我尝试过的一个查询,并且已成功执行。但是,当您必须为超过300个变量设计相同的查询时,这将是一项非常痛苦的任务。考虑到我们有超过300个变量,是否有任何有效的方法来完成相同的任务?感谢您的评论!

    select t.id,max(t.s_amt) as s_amt,max(t.s_a_amt) as s_a_amt, max(t.s_b_amt) as s_b_amt
  from
     (select s1.id,sum(amount) as s_amt,0 as s_a_amt,0 as s_b_amt from sales s1 group by id union all
     select s2.id, 0 as s_amt, sum(amount) as s_a_amt, 0 as s_b_amt from sales s2 where ptype='a' group by id union all
     select s3.id, 0 as s_amt,0 as s_a_amt, sum(amount) as s_b_amt from sales s3 where ptype='b' group by id) t
group by t.id;

3 个答案:

答案 0 :(得分:2)

理想的解决方案是拥有

  

IBM指的物化查询表(MQT)。

汇总表是MQT的特殊形式,这正是您所需要的。快速定义 - 顾名思义,MQT是一个简单的汇总表,在磁盘上实现。

有了MQT支持,您只需要执行以下操作

CREATE MATERIALISED QUERY TABLE MQTA AS (
select id, sum(amount) as s_a_amt from sales where ptype='a' group by id;
)
Data initially deferred 
Refresh deferred
Maintained by User

最初推迟的数据表示不将摘要记录插入摘要表。 刷新延迟表示可以使用 REFRESH TABLE 语句随时刷新表格中的数据。 由用户维护表示用户必须注意此表的参考 - 由系统维护是系统负责自动更新摘要表的另一个选项基表可以看到插入/删除//更新。

您可以直接查询MQT,就像一个简单的选择查询一样,所有繁重的汇总记录实际上都会先运行,而不是在查询MQT时会更快。

但AFAIK HIVE不支持MQT或汇总表。

您现在已经了解了这个概念,您只需要简单地模拟它。创建一个汇总表并插入汇总记录(REFRESH TABLE概念)。您必须通过控制某种最后加载日期字段来定期加载汇总值,这样您将在上次刷新后仅拾取记录。您可以使用预定作业执行此操作 - Hive脚本。

INSERT INTO PTYPE_AMOUNT_MQT AS (
select *
  from
     (select s1.id,sum(amount) as s_amt,0 as s_a_amt,0 as s_b_amt from sales s1 where record_create_date > last_Refresh_date group by id union all
     select s2.id, 0 as s_amt, sum(amount) as s_a_amt, 0 as s_b_amt from sales s2 where ptype='a' and record_create_date > last_Refresh_date  group by id union all
     select s3.id, 0 as s_amt,0 as s_a_amt, sum(amount) as s_b_amt from sales s3 where ptype='b'  and record_create_date > last_Refresh_date group by id) 
)

拥有像record_create_date和time这样的审计字段总是好的.last_Refresh_date是 上一次你的工作

答案 1 :(得分:1)

解决方案应该是:

select id, sum(amount) s_amt, 
        SUM (CASE WHEN ptype='a' THEN amount 
                       ELSE 0
        END) sum_a_amt,
        SUM (CASE WHEN ptype='b' THEN amount 
                       ELSE 0
        END) sum_b_amt
from sales 
group by id;

请尝试并告诉我它是否有效,我现在无法测试......

答案 2 :(得分:1)

Hive最近添加了GROUPING SETS作为新功能(https://issues.apache.org/jira/browse/HIVE-3471)。它比MQT容易(写或读)。但并非每个人都知道这个功能,正如Arnaud所说,CASE功能的使用在实践中更常用。