对行进行分组,以便每组列的总和不超过10

时间:2019-06-25 07:18:38

标签: sql hadoop hive

我有一个看起来像这样的表

col1
------
2
2
3
4
5
6
7

其值按升序排序。

我想将每行分配给标签为0,1,...,n的组,以便每个组的总数不超过10。因此在上面的示例中,它看起来像这样:

col1 |label
------------
2   0
2   0
3   0
4   1
5   1
6   2
7   3

我尝试使用此:

floor(sum(col1) OVER (partition by  ORDER BY col1 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) /10))

但这不能正常工作,因为它正在执行操作 为:

floor(2/10) = 0
floor([2+2]/10) = 0
floor([2+2+3]/10) = 0
floor([2+2+3+4]/10) = 1
floor([2+2+3+4+5]/10 = 1
floor([2+2+3+4+5+6]/10 = 2
floor([2+2+3+4+5+6+7]/10) = 2

巧合的是,直到上一次计算都是正确的,因为即使

[2+2+3+4+5+6+7] / 10 = 2.9

floor(2.9) = 2

应该做的是意识到6 + 7是> 10,因此具有值7的第5行需要在其自己的组中,因此迭代组号+ 1并将该行分配到一个新组中。

我真正想做的是遇到一个总和> 10,然后将组号=组号+ 1,将CURRENT ROW分配到这个新组中,然后最后将新的开始行设置为CURRENT ROW

1 个答案:

答案 0 :(得分:0)

这个评论太长了。

要解决此问题,需要逐行扫描表。在SQL中,这将通过递归CTE(或分层查询)进行。 Hive不支持这些。

问题在于,每次定义一个组时,“ 10”和总和之间的差就会被“遗忘”。也就是说,当您在列表中靠后时,更早发生的事情不是简单地累积可用数据。您需要知道如何将其分组。

一个相关的问题 是可以解决的。相关的问题是将所有行分配给大小为10的组,将行分成两组。然后,仅根据前几行的累加和就知道下一行在哪个组中。