【问题标题】:Best Hive SQL query for this对此的最佳 Hive SQL 查询
【发布时间】:2017-05-07 06:37:45
【问题描述】:

我有 2 张这样的桌子。我正在运行 Hive 查询,并且 Windows 功能在 Hive 中似乎非常有限。

餐桌部

id | name |
1 | a |
2 | b |
3 | c |
4 | d |

表时间(使用重负载查询构建,因此如果我需要加入另一个新创建的表时间,这将是一个非常缓慢的过程。)

id | date | first | last |
1 | 1992-01-01 | 1 | 1 |
2 | 1993-02-02 | 1 | 2 |
2 | 1993-03-03 | 2 | 1 |
3 | 1993-01-01 | 1 | 3 |
3 | 1994-01-01 | 2 | 2 |
3 | 1995-01-01 | 3 | 1 |

我需要检索这样的东西:

SELECT d.id,d.name,
t.date AS firstdate,
td.date AS lastdate
FROM dbo.dept d LEFT JOIN dbo.time t ON d.id=t.id AND t.first=1
LEFT JOIN time td ON d.id=td.id AND td.last=1

如何得到最优化的答案?

【问题讨论】:

  • 将常量比较(即t.first=1)放在where 子句中,而不是join 子句中。除此之外,这看起来很简单。
  • @Donnie 我是这些蜂巢表的新手,这个时间表是由一个复杂的SELECT 查询构建的,我想做的是让时间表只被调用一次,这可能吗? @TimBiegeleisen 我需要一个查询来完成此操作。而且这个表是由繁重的工作构建的,实际上最好的方法是使用临时表,但我不知道如何在 hive 中使用它是最好的。
  • @Donnie - 这在逻辑上不等同于原始查询
  • 我假设每个部门first/last = 1 的行不超过一行?
  • 是的,它们是由行号生成的,我只是将其简化为有问题的临时表。

标签: sql hive hiveql memory-optimized-tables


【解决方案1】:

GROUP BY 将在单个 map-reduce 作业中完成的操作

select      id
           ,max(name)   as name
           ,max(case when first = 1 then `date` end) as firstdate
           ,max(case when last  = 1 then `date` end) as lastdate

from       (select      id
                       ,null as name 
                       ,`date`         
                       ,first         
                       ,last 

            from        time

            where       first = 1
                    or  last  = 1

            union all  

            select      id 
                       ,name         
                       ,null as `date` 
                       ,null as first 
                       ,null as last  

            from        dept
            ) t

group by    id 
;

+----+------+------------+------------+
| id | name | firstdate  |  lastdate  |
+----+------+------------+------------+
|  1 | a    | 1992-01-01 | 1992-01-01 |
|  2 | b    | 1993-02-02 | 1993-03-03 |
|  3 | c    | 1993-01-01 | 1995-01-01 |
|  4 | d    | (null)     | (null)     |
+----+------+------------+------------+      

【讨论】:

  • 查看更新的答案(根据新数据样本调整)
  • 非常感谢先生,保存它!
  • 不客气。附:请参阅更新的答案以添加可能提高性能的 WHERE 子句。
【解决方案2】:
select      d.id
       ,max(d.name)   as name
       ,max(case when t.first = 1 then t.date end) as 'firstdate'
       ,max(case when t.last  = 1 then t.date end) as 'lastdate'

from      dept d  left join  
      time t on d.id = t.id
where     t.first = 1  or  t.last  = 1
group by  d.id

【讨论】:

  • 我实际上已经在使用这种查询,从第一个答案中获取查询逻辑的要点,UNION ALL 比正常的JOIN 更快。不过还是谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-19
  • 2015-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-30
  • 2018-08-30
相关资源
最近更新 更多