如何设置条件自动增加列值

问题描述

我有这样的桌子:

value nextValue
1     2
2     3
3     20
20    21
21    22
22    23
23    NULL

值是按ASC排序的,nextValue是下一行的值。 要求按条件nextValue-value> 10分组,并计算不同组中有多少个值。

例如,应该有两组(1,2,3)(20,21,22,23),第一组计数为3,第二组计数为4。

我正在尝试用唯一的数字标记每个组,因此我可以按这些标记的数字进行分组

value nextValue mark
1     2         1
2     3         1
3     20        1
20    21        2
21    22        2
22    23        2
23    NULL      2

但是我不知道如何写标记列,nextValue-value>10时需要一个自增变量。 我可以在Hive中实现它吗?还是有更好的解决方案?

解决方法

计算先前的值,如果value-prev_value> 10,则计算new_group_flag,然后计算new_group_flag的累积总和以获取组号(标记)。最后,您可以使用分析功能或分组依据来计算组计数(在我的示例中,分析计数用于向您显示所有中间计算的完整数据集)。查看代码中的注释。

演示:

with your_data as (--use your table instead of this
select stack(10,--the number of tuples generated
1,2,3,20,21,22,23,40,41,42
) as value
)

select --4. Calculate group count,etc,etc
       value,prev_value,new_group_flag,group_number,count(*) over(partition by group_number) as group_count
from
(
select --3. Calculate cumulative sum of new group flag to get group number
       value,sum(new_group_flag) over(order by value rows between unbounded preceding and current row)+1 as group_number
from
(
select --2. calculate new_group_flag
       value,case when value-prev_value >10 then 1 else 0 end as new_group_flag
from
(
select  --1 Calculate previous value
      value,lag(value) over(order by value) prev_value
  from your_data
)s
)s
)s

结果:

value  prev_value  new_group_flag  group_number   group_count
1       \N           0              1              3
2       1            0              1              3
3       2            0              1              3
20      3            1              2              4
21      20           0              2              4
22      21           0              2              4
23      22           0              2              4
40      23           1              3              3
41      40           0              3              3
42      41           0              3              3
,

如果我的理解正确,您可以使用累计金额。这个想法是在next_value - value > 10时设置一个标志。这标识了组。因此,此查询添加了一个组号:

select t.*,sum(case when nextvalue > value + 10 then 1 else 0 end) over (order by value desc) as mark
from t
order by value;

您可能无法找到令人满意的解决方案,因为编号是按降序排列的。因此,更多的算法修复了该问题:

select t.*,(sum(case when nextvalue > value + 10 then 1 else 0 end) over () + 1 -
        sum(case when nextvalue > value + 10 then 1 else 0 end) over (order by value desc)
       ) as mark
from t
order by value;

Here是db 小提琴。

,

这对我有用 在我的情况下,它需要“在前一行和当前行之间无限制的行”。

select t.*,sum(case when nextvalue > value + 10 then 1 else 0 end) over (order by value desc rows between unbounded preceding and current row) as mark
from t
order by value;