在蜂巢中,如何在2行之间进行计算?

时间:2013-05-15 06:42:11

标签: hive hiveql

我有这张桌子。

   +------------------------------------------------------------+
   |     ks      |      time     |     val1      |    val2      | 
   +-------------+---------------+---------------+--------------+
   |     A       |       1       |       1       |      1       |
   |     B       |       1       |       3       |      5       |
   |     A       |       2       |       6       |      7       |
   |     B       |       2       |      10       |     12       |
   |     A       |       4       |       6       |      7       |
   |     B       |       4       |      20       |     26       |
   +------------------------------------------------------------+

我想得到的是每一行,

ks |  time |  val1 | val1 of next ts of same ks  |

要明确,上面例子的结果应该是,

   +------------------------------------------------------------+
   |     ks      |      time     |     val1      |   next.val1  | 
   +-------------+---------------+---------------+--------------+
   |     A       |       1       |       1       |       6      |
   |     B       |       1       |       3       |       10     |
   |     A       |       2       |       6       |       6      |
   |     B       |       2       |      10       |       20     |
   |     A       |       4       |       6       |      null    |
   |     B       |       4       |      20       |      null    |
   +------------------------------------------------------------+

(我也需要同样的值2)

我尝试了很多为此提出的hive查询,但仍然没有运气。我能够在sql中编写一个查询,如here(Quassnoi的回答),但无法在hive中创建等效项,因为hive不支持select中的子查询。

有人可以帮助我实现这个目标吗?

提前致谢。

编辑:

我试过的查询是,

SELECT ks, time, val1, next[0] as next.val1 from
(SELECT ks, time, val1
       COALESCE(
       (
       SELECT Val1, time
       FROM myTable mi
       WHERE mi.val1 > m.val1 AND mi.ks = m.ks
       ORDER BY time
       LIMIT 1
       ), CAST(0 AS BIGINT)) AS next
FROM  myTable m
ORDER BY time) t2;

2 个答案:

答案 0 :(得分:2)

您的查询似乎与财务报告中无处不在的“年前”报告非常相似。我认为你正在寻找LEFT OUTER JOIN

我们将表myTable加入到自身,命名同一个表mn的两个实例。对于第一个表m中的每个条目,我们将尝试在n中找到具有相同ks值但增加值time的匹配记录。如果此记录不存在,n的所有列值都将为NULL

SELECT 
    m.ks, 
    m.time,
    m.val1, 
    n.val1 as next_val1,
    m.val2, 
    n.val2 as next_val2
FROM 
    myTable m
LEFT OUTER JOIN
    myTable n
ON (
    m.ks = n.ks
AND 
    m.time + 1 = n.time
);

返回以下内容。

ks  time  val1  next_val1  val2  next_val2
A   1     1     6          1     7
A   2     6     6          7     7
A   3     6     NULL       7     NULL
B   1     3     10         5     12
B   2     10    20         12    26
B   3     20    NULL       26    NULL

希望有所帮助。

答案 1 :(得分:2)

我发现使用Hive自定义map / reduce功能非常适合解决与此类似的查询。它使您有机会考虑一组输入并“减少”到一个(或多个)结果。

answer讨论了解决方案。

关键是你使用CLUSTER BY将具有相似键值的所有结果发送到同一个reducer,因此相同的reduce脚本,相应地收集,然后在键更改时输出缩小的结果,并开始收集新钥匙。