1

我有时间戳数据,并希望从一列创建一个列表,将相邻的重复项(但不是所有重复项)折叠成一个。

例如,给定以下数据:

'2001-01-01 00:00:01' 'a'
'2001-01-01 00:00:02' 'a'
'2001-01-01 00:00:03' 'b'
'2001-01-01 00:00:04' 'b'
'2001-01-01 00:00:05' 'b'
'2001-01-01 00:00:06' 'a'
'2001-01-01 00:00:07' 'a'
'2001-01-01 00:00:08' 'c'
'2001-01-01 00:00:09' 'a'

— 我希望结果是'a','b','a','c','a'

我正在使用 Snowflake,它有listagg(distinct foo)andlistagg(distinct foo) within group(order by bar)甚至listagg(distinct foo) within group(order by bar) over(partition by baz),但我看不到做我需要的方法(谷歌也没有帮助)。我真的,真的很想避免join.

如果您知道另一种方言中具有listagg或的解决方案group_concat,请将其发布,我将尝试将其翻译成 Snowflake 以供我使用。非常感谢。


不起作用的事情:

  • 我试过了trim(regexp_replace('~' || listagg(foo, '~') || '~', '~([^~]+~)\\1', '~\\1'), '~'),但是 Snowflake 不允许\1在匹配模式中:我得到了错误Invalid regular expression: '~([^~]+~)\1', invalid escape sequence: \1
  • 我试过listagg(iff(lag(foo) ignore nulls over(partition by baz order by bar)=foo, null, foo), ',') within group(order by bar) over(partition by baz)但得到了错误Window function [LAG(...)] may not be nested inside another window function.
4

1 回答 1

0

不幸的是,我认为 Snowflake 不支持正则表达式模式中的反向引用。

可能的解决方案:

  • 使用 LAG 消除输入流中的重复项,例如

    with sub as (select foo, bar, lag(bar) over (order by foo) barlag)
    select listagg(foo) within group order by (bar) from foo 
    where barlag is null or barlag <> lag;
    
  • 使用 LISTAGG,但编写一个 JavaScript UDF 来拆分 LISTAGG 的结果并消除那里的重复项

  • 编写一个执行 LISTAGG 并消除重复的 JavaScript UDTF(表函数)
于 2018-06-19T18:14:09.353 回答