Calc 跨 Redshift 中的连续值组聚合

Posted

技术标签:

【中文标题】Calc 跨 Redshift 中的连续值组聚合【英文标题】:Calc aggregates across continuous groups of values in Redshift 【发布时间】:2020-02-26 18:42:51 【问题描述】:

这可能很容易编写解决方案,但很难在直接 SQL 中完成。我可能不得不放弃并编写一个扫描表格的例程。

我有一个用户状态值表,其中包含如下开始和结束日期:

create table #t (userid int4, status varchar(15), start_time date, end_time date);

insert into #t values
(1, 'Active', '2019-08-15', '2019-08-20'),
(1, 'Active', '2019-08-20', '2019-08-22'),
(1, 'Active', '2019-08-22', '2019-09-22'),
(1, 'Inactive', '2019-09-22', '2019-10-22'),
(1, 'At Risk', '2019-10-22', '2019-11-22'),
(1, 'Lapsed', '2019-11-22', '2019-12-08'),
(1, 'Active', '2019-12-08', '2019-12-18'),
(1, 'Active', '2019-12-18', '2020-01-11'),
(1, 'Active', '2020-01-11', '2020-01-15'),
(1, 'Active', '2020-01-15', '2020-02-15'),
(1, 'Inactive', '2020-02-15', '2020-03-15')
;

我正在尝试将每组连续状态值的最小/最大日期汇总(按 start_time 排序时),如下所示:

我一直在尝试通过在 Redshift 中使用窗口函数来实现这一目标,但我无法根据状态进行分区,因为这似乎将状态组合在一起,从 2019 年 8 月 15 日到 2020 年我最终得到“活动”- 02-15.

【问题讨论】:

我正在使用手机,所以我需要很长时间才能输入查询。但是你需要的方法被称为差距和孤岛。这是一种使用窗口函数来识别所需组的相对优雅的方式。 【参考方案1】:

这是一种所谓的差距和孤岛方法。写在我的手机上,所以未经测试。但是您应该能够搜索 SO 以找到该关键短语。

WITH
  sorted AS
(
  SELECT
    *, 
    ROW_NUMBER()
      OVER (
        PARTITION BY userid
            ORDER BY start
      )
        AS row_userid_start,
    ROW_NUMBER()
      OVER (
        PARTITION BY userid, status
            ORDER BY start
      )
        AS row_userid_status_start
  FROM
    #t
)
SELECT
  userid,
  status,
  MIN(start)   AS start,
  MAX(end)     AS end
FROM
  sorted
GROUP BY
  userid,
  status,
  row_userid_status_start - row_userid_start

【讨论】:

以上是关于Calc 跨 Redshift 中的连续值组聚合的主要内容,如果未能解决你的问题,请参考以下文章

连续编号的值组(包括重复)

具有动态 SQL 语句的 Redshift UDF 函数

对 pandas 数据框中的连续值进行分组

参考 Amazon Redshift 查询中的聚合结果?

R - 对连续变量标题进行分组,将分类变量因子作为行并聚合为最小值、最大值、平均值

(REDSHIFT) 垂直合并 / FIRST_VALUE() 作为聚合