如何设置带条件的自动递增列值

um6iljoc  于 2021-06-24  发布在  Hive
关注(0)|答案(3)|浏览(301)

我有这样的table:

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。
我试着用唯一的数字来标记每个组,这样我就可以用这些标记的num来分组

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

但是我不知道怎么写标记列,我需要一个autocrement变量 nextValue-value>10 . 我能在 hive 里做吗?或者有更好的解决方案?

7qhs6swi

7qhs6swi1#

计算上一个值,如果value-prev\u值>10,则计算新\u组\u标志,然后计算新\u组\u标志的累计和,得到组号(mark)。最后,您可以使用analytics函数或group by计算组计数(在我的示例中,analytics计数用于显示包含所有中间计算的完整数据集)。请参见代码中的注解。
演示:

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, prev_value, new_group_flag, 
       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, prev_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
egmofgnx

egmofgnx2#

这对我来说很有用,在我的例子中,它需要“无界前一行和当前行之间的行”。

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;
xn1cxnb4

xn1cxnb43#

如果我理解正确的话,你可以用累计和。我们的想法是在 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;

这是一把小提琴。

相关问题