Redshift LISTAGG框架子句

时间:2018-03-21 21:02:14

标签: sql amazon-redshift

我正在尝试聚合字符串,但仅限于前面的行,而不是整个分区。有没有人知道如何在Redshift中执行此操作?

我想要实现的目标是下面的appended_event_namespace列。

enter image description here

这是我到目前为止所尝试过的。

LISTAGG(event_namespace, '/')
WITHIN GROUP (ORDER BY tstamp_true)
OVER (PARTITION BY acct_id) AS appended_event_namespace

这导致每一行都有完整的ApplicationLaunch/CategoryBrowse/NotificationCenter/UserProfile聚合,而不是所需屏幕截图中的聚合。

困难在于它只能追加到当前行,因为似乎没有Redshift的LISTAGG()的frame子句。感谢任何有用的想法。

2 个答案:

答案 0 :(得分:0)

您可以将其与其他查询一起破解。作为原始LISTAGG

的结果,从您的attached_event_namespace开始
SELECT event_namespace,
  SUBSTRING(appended_event_namespace,
            1, 
            POSITION(event_namespace,appended_event_namespace) + LEN(event_namespace) - 1
  ) as appended_event_namespace_cum
FROM your_table;

基本上,你采用聚合的,有序的字符串,然后取N所在的前N个字符([它出现在聚合字符串中的位置] + [它的长度]),这将删除该项目之后的所有内容。这为您提供了累积命名空间。

答案 1 :(得分:0)

RS中不支持带有frame子句的

LISTAGG。如果你有一些可用于分区和排序的列,你可以进行自我加入(不是那么高效,但会达到你想要的效果):

SELECT 
 t1.id
,t2.tstamp_true
,t1.event_namespace
,LISTAGG(t2.event_namespace,'/') WITHIN GROUP (ORDER BY t2.tstamp_true)
FROM your_table t1
JOIN your_table t2
ON t1.id=t2.id
AND t1.tstamp_true>=t2.tstamp_true
GROUP BY 1,2,3

或者,如果您想避免自连接,可以使用LISTAGG构建具有以下结构的JSON:

[{tstamp_true_1,event_namespace_1},{tstamp_true_N,event_namespace_N},...]

并编写一个Python UDF,它为给定行的给定行和tstamp_true获取此类JSON并返回路径(该函数需要在第二行之前过滤tstamp_true_N值参数并连接输出的过滤的event_namespace_N