1

我正在尝试检测配置单元表列中的序列。我有 3 列(id、标签、索引)。每个 id 都有一个标签序列, index 是标签的顺序,比如

id  label   index
a   x   1
a   y   2
a   x   3
a   y   4
b   x   1
b   y   2
b   y   3
b   y   4
b   x   5
b   y   6

我想确定是否出现 x,y,x,y 的标签序列。
我正在考虑尝试使用主要功能来完成此操作,例如:

select id, index, label,
lead( label, 1) over (partition by id order by index) as l1_fac,
lead( label, 2) over (partition by id order by index) as l2_fac,
lead( label, 3) over (partition by id order by index) as l3_fac
from mytable

产量:

id  index  label  l1_fac  l2_fac  l3_fac
a  1  x  y  x  y
a  2  y  x  y  NULL
a  3  x  y  NULL  NULL
a  4  y  NULL  NULL  NULL
b  1  x  y  y  y
b  2  y  y  y  x
b  3  y  y  x  y
b  4  y  x  y  NULL
b  5  x  y  NULL  NULL

其中 l1(2,3) 是下一个标签值。然后我可以检查一个模式

where label = l2_fac and l1_fac = l3_fac

这适用于 id = a,但不适用于标签序列为:x、y、y、y、y、x 的 id = b。我不在乎它是连续 3 年,我只是对它从 x 到 y 再到 x 到 y 感兴趣。

我不确定这是否可能,我正在尝试分组和分区的组合,但没有成功。

4

1 回答 1

0

我回答了这个问题,其中 OP 想要将项目收集到列表中并删除任何重复的项目。我认为这基本上是你想要做的。这将提取实际 xyxy序列,也将解释您的第二个示例xyxy发生的位置,但会被 2 个额外y的 s 覆盖。您需要使用此 UDAFlabel将列收集到一个数组中- 这将保留顺序 - 然后使用我引用的 UDF,然后您可以使用将该数组的内容设为字符串,最后,检查该字符串的出现您想要的序列。该函数将吐出第一次出现的位置,如果它从未找到该字符串,则为零。concat_wsinstr

查询

add jar /path/to/jars/brickhouse-0.7.1.jar;
add jar /path/to/other/jar/duplicates.jar;

create temporary function remove_seq_dups as 'com.something.RemoveSequentialDuplicates';
create temporary function collect as 'brickhouse.udf.collect.CollectUDAF';

select id, label_string, instr('xyxy', label_string) str_flg
from (
  select id, concat_ws('', no_dups) label_string
  from (
    select id, remove_seq_dups(label_array) no_dups
    from (
        select id, collect(label) label_array
        from db.table
        group by id ) x
        ) y
     ) z

输出

id   label_string    str_flg
============================
a    xyxy            1
b    xyxy            1

一个更好的选择可能是简单地label使用 UDF 进行收集,使其成为一个字符串,然后正则表达式输出序列xyxy,但我在正则表达式方面非常糟糕,所以可能其他人可以对此进行智能评论。

于 2015-07-22T15:03:10.463 回答