我试图在我的蜂巢表的一列中检测序列。我有3列 (id,label,index)。每个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,但不适用于id = b,其中标签序列为:x,y,y,y,y,x。我不在乎它是连续3年我感兴趣的是它从x到y到x到y。
我不确定这是否可行,我正在尝试分组和分区的组合,但没有成功。
答案 0 :(得分:0)
我回答了this question,其中OP想要将项目收集到列表中并删除任何重复项目。我认为这基本上就是你想要做的。这将提取实际的 xyxy
序列,并且还会考虑您xyxy
出现的第二个示例,但会被2个额外的y
所遮蔽。您需要使用this UDAF将label
列收集到数组中 - 这将保留顺序 - 然后使用我引用的UDF,然后您可以使用concat_ws
来生成内容这个数组是一个字符串,最后,检查该字符串是否出现所需的序列。函数instr
将吐出第一次出现的位置,如果它从未找到该字符串,则为零。
<强>查询强>:
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
更好的替代方法可能是简单地使用UDF收集label
,将其设为字符串,然后将序列xyxy
重新编号,但我在正则表达式中非常可怕,所以可能是其他人可以聪明地评论这个。