sql - 重叠区间的总长度

标签 sql amazon-redshift

我在 Redshift 数据库中有一个表,其中包含分组且可能重叠的间隔,如下所示:

| interval_id | l  | u  | group |
| ----------- | -- | -- | ----- |
| 1           | 1  | 10 | A     |
| 2           | 2  | 5  | A     |
| 3           | 5  | 15 | A     |
| 4           | 26 | 30 | B     |
| 5           | 28 | 35 | B     |
| 6           | 30 | 31 | B     |
| 7           | 44 | 45 | B     |
| 8           | 56 | 58 | C     |

我想做的是确定组内间隔的并集长度。也就是说,对于每个间隔,取 u - l,对所有组成员求和,然后减去间隔之间重叠的长度。

期望的结果:

| group | length |
| ----- | ------ |
| A     | 14     |
| B     | 10     |
| C     | 2      |

这个问题has been asked before可惜该线程中的所有解决方案似乎都使​​用了 Redshift 不支持的功能。

最佳答案

这并不困难,但需要多个步骤。关键是定义每个组内的“岛屿”,然后对这些“岛屿”进行聚合。许多子查询、聚合和窗口函数。

select groupId, sum(ul)
from (select groupId, (max(u) - min(l) + 1) as ul
      from (select t.*,
                   sum(case when prev_max_u < l then 1 else 0 end) over (order by l) as grp
            from (select t.*,
                         max(u) over (order by l rows between unbounded preceding and 1 preceding) as prev_max_u
                  from t
                 ) t
           ) t
      group by groupid, grp
     ) g
group by groupId;

这个想法是确定每个记录的开头是否存在重叠。为此,它对所有先前记录使用累积最大值函数。然后,它通过将之前的最大值与当前的 l 进行比较来确定是否存在重叠——重叠的累积和定义了一个组。

剩下的只是聚合。还有更多聚合。

关于sql - 重叠区间的总长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42636540/

相关文章:

SQL 在所有列中选择唯一的表行

sql - 一周的第一天(从星期日开始)

mysql - 多列子查询不适用于笛卡尔积

sql - 在 SQL 数据库中的 WHERE 条件下使用的每一列上创建索引是一种好习惯吗?

amazon-web-services - Amazon Redshift 是否支持扩展 dblink?

amazon-web-services - RedShift 节点故障转移

sql - BigQuery SQL 如何在使用 LIMIT 时获取总计数

mysql - 为什么 MySQL 查询需要 1 毫秒到 7 秒?

mysql - 什么是独立于数据库(适用于 mysql 和 sqlite3)的解决方案来计算 SQL 中两个日期之间的天数?

hadoop - HIVE - 将大型有序查询结果集拆分为多个顺序文件