在SELECT中添加主动计数器

时间:2015-04-10 00:56:57

标签: sql oracle hive

我有一张这样的表:

Row#    ID    Indicator
 1      001      Yes
 2      001      No
 3      001      No
 4      001      No
 5      001      No
 6      001      Yes
 7      001      No
 8      002      No
 9      002      No
 10     002      No
 11     002      No
 12     002      No
 13     002      No
 14     002      Yes
 15     002      No
 16     003      No
 17     003      Yes
 18     003      No
 19     003      No
 20     003      No
 21     003      No
 22     004      No
 .        .      .
 .        .      .
100     020      Yes

我想要一个计数器,计算每3个连续'否'的数量和按ID分组。计数器功能在看到“否”时触发。一旦连续出现3行“否”,counter = counter + 1.不允许重复计数。

例如:
对于ID = 001,从第2行到第4行有三个连续的“否”,因此计数器值= 1。

由于使用了从第2行到第4行的“否”,因此第3行到第5行不能算作事件 没有重复计数规则。

对于ID = 002,从第8行到第10行有三个连续的“否” 从第11行到第13行,所以计数器值= 2。

所需的输出如下:

ID    Counter
001      1
002      2
003      1
 .       .
 .       .
100      0

编辑1:行#不是真正的列。这是出于解释目的。
编辑2:我意识到行#对这个问题至关重要。让我们再次成为一个真正的专栏。所以上面给出的原始数据样本仍然有效。

1 个答案:

答案 0 :(得分:1)

Hive支持row_number(),因此您可以使用它来枚举值。一开始逻辑可能并不明显,但想法是枚举连续的" N"将结果除以3。后一部分是获取所需序列数的逻辑。

以下版本假设只有一个长序列的" N" s。这是问题中数据的格式:

select t.id, max(floor(seqnum / 3.0))
from (select t.*,
             row_number() over (partition by id, indicator, grp order by row#) as seqnum
      from (select t.*,
                   (row_number() over (partition by id order by row#) -
                    row_number() over (partition by id, indicator order by row#)
                   ) as grp
            from table t
           ) t
     ) t
where indicator = 'N'
group by id;

这可以修改为处理给定id的多个" N" s,但查询有点复杂。

编辑:

我意识到以下内容更为通用:

select t.id, sum(case when pmod(seqnum, 3) = 0 then 1 else 0 end)