【问题标题】:Using window function in redshift to aggregate conditionally在redshift中使用窗口函数有条件地聚合
【发布时间】:2020-06-01 04:20:06
【问题描述】:

我有一个包含以下数据的表格:

测试数据链接:http://sqlfiddle.com/#!15/dce01/1/0

我想按照 seq 列指定的顺序聚合 gid 中每个组的 items 列(使用 listagg),基于当 pid 再次变为 0 时聚合结束的条件。

即 对于组 g1,将有 2 个聚合; 1 用于序列 1-3,另一个用于序列 4-6;因为对于组 g1,对于 seq 4,pid 变为 0。

我希望给定示例的结果如下(请注意,结果中的seq 是 pid 变为 0 的组的 seq 的最小值):

【问题讨论】:

  • @a_horse_with_no_name:我需要在 redshift 上运行查询。但是,由于 sqlfiddle 没有用于 redshift 引擎的选项,因此我使用 postgres db 创建了测试数据,原因与您指出的完全相同(关于它们共享共同的根)。此外,postgres 查询可以与 redshift 中的一些 mod 一起运行,例如。 listagg postgres 的替代方案是 string_agg

标签: sql group-by amazon-redshift window-functions gaps-and-islands


【解决方案1】:

我将您的问题理解为间隙和孤岛问题,您希望将具有相同 gid 的相邻行组合在一起,直到满足具有值 0pid

这是使用窗口总和来定义组的一种解决方法:基本上,每次遇到0 的 pid 时都会启动一个新岛。剩下的只是聚合:

select
    gid,
    min(seq) seq,
    listagg(items, ',') within group(order by seq) items
from (
    select 
        t.*,
        sum(case when pid = 0 then 1 else 0 end) over(partition by gid order by seq) grp
    from mytable t
) t
group by gid, grp
order by gid, grp

【讨论】:

  • 谢谢...那行得通...我已经把工作的postgres版本的查询here
  • 我们还需要在 sum 聚合中的 order by 子句之后添加 rows unbounded preceding,否则 redshift 会输出错误消息“运行查询时出错:带有 ORDER BY 子句的聚合窗口函数需要一个框架子句”
【解决方案2】:

这是间隙和孤岛问题:

with
 subgroup_ids as (
    select *, sum(case when pid=0 then 1 else 0 end) over (partition by gid order by seq) as subgroup_id
    from tablename
)
select gid, subgroup_id, listagg(items,',')
from subgroup_ids
group by 1,2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-29
    相关资源
    最近更新 更多