我有一个看起来像这样的表:
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 .
最佳答案
评论太长了。
解决这个问题需要逐行扫描表。在 SQL 中,这将通过递归 CTE(或分层查询)实现。 Hive 不支持这两种方式。
问题是每次定义一个组时,10 和总和之间的差值就会被“遗忘”。也就是说,当您在列表中更靠下时,较早发生的事情并不是可用数据的简单累积。您需要知道它是如何分组的。
一个相关的问题是可以解决的。相关问题会将所有行分配给大小为 10 的组,将行拆分为两个组。然后你就可以根据前面几行的累加和知道后面一行属于哪个组。
关于sql - 对行进行分组,使每组的列总和不超过 10,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56748736/