在postgres中合并日期范围以消除重叠

用户

如果我有一个postgres表,请执行以下操作:

  member |    start   |    end
---------+------------+------------
    1    | 2015-01-01 | 2015-05-01
---------+------------+------------
    1    | 2015-03-01 | 2015-06-01
---------+------------+------------
    2    | 2015-01-01 | 2015-05-01
---------+------------+------------
    2    | 2015-06-01 | 2015-08-01

我如何合并日期以消除像这样的重叠范围:

  member |    start   |    end
---------+------------+------------
    1    | 2015-01-01 | 2015-06-01
---------+------------+------------
    2    | 2015-01-01 | 2015-05-01
---------+------------+------------
    2    | 2015-06-01 | 2015-08-01
埃戈尔·罗戈夫(Egor Rogov)

chopCTE中,原始范围被“切成”较小的,不相交(但可能相邻)的范围。它们是从原始范围的所有端点(包括起点和终点)构建的。

Main select的工作方式如下(从内而外读取):

  1. 当一个范围与先前的范围相邻时,该范围的相邻标志为零(假设范围按其开始日期排序)。
  2. 相邻标志的累加总和为我们提供了一个分组值:所有相邻范围将具有相同的总和。
  3. 最外面的块仅计算相邻范围范围的边界值。

窗口功能的黑魔法...

with chop as (
  select member,
         pt as start,
         lead(pt) over (partition by member order by pt) finish,
         (
           select count(*)
           from   a
           where  b.member = a.member
           and    b.pt >= a.start
           and    b.pt < a.finish
         ) need_it
  from   (
           select member, start pt from a
           union
           select member, finish pt from a
         ) b
)
-- 3
select member,
       min(start),
       max(finish)
from   (
         -- 2
         select member,
                start,
                finish,
                sum(adjacent) over (partition by member order by start) grp
         from   (
                  -- 1
                  select member,
                         start,
                         finish,
                         case
                           when start <= lag(finish) over (partition by member order by start)
                           then 0
                           else 1
                         end adjacent
                  from   chop
                  where  need_it > 0
                ) t
       ) q
group by member,
         grp
order by member,
         min(start);

我改名为endfinish因为它end是一个关键字。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在SQL中合并具有重叠日期范围的记录

来自分类Dev

如何在MySQL中合并重叠的日期范围?

来自分类Dev

在SQL中检测和合并日期范围的连续重叠

来自分类Dev

在SQL中合并具有重叠日期范围的记录

来自分类Dev

在PostgreSQL中合并重叠的时间范围

来自分类Dev

在PostgreSQL中合并重叠的时间范围

来自分类Dev

MySQL合并具有重叠日期范围的表行

来自分类Dev

SQL Server 2014 合并重叠日期范围

来自分类Dev

在SQL中查找日期范围重叠的记录

来自分类Dev

合并数字的重叠范围

来自分类Dev

合并记录以重叠日期

来自分类Dev

多次重叠的日期范围

来自分类Dev

在SQL表中合并重叠的日期间隔

来自分类Dev

Postgres表中的更新日期范围

来自分类Dev

如何在PHP中检查多个日期范围之间的重叠?

来自分类Dev

在两个表中查找重叠的日期范围

来自分类Dev

如何在PHP中检查多个日期范围之间的重叠?

来自分类Dev

如何从重叠的日期范围中检索计数?

来自分类Dev

合并重叠日期的记录

来自分类Dev

如何将两个数据框与重叠日期时间范围内的列合并

来自分类Dev

计算重叠日期范围的价格

来自分类Dev

如何查询重叠的日期范围?

来自分类Dev

合并日期范围

来自分类Dev

测试日期范围不重叠的范围

来自分类Dev

测试日期范围不重叠的范围

来自分类Dev

计算多个日期范围之间的分钟数,但不要计算MongoDB中的重叠日期

来自分类Dev

计算日期数组中重叠的天数到固定的日期范围

来自分类Dev

如何根据日期范围合并 Pandas Dataframe 中的行

来自分类Dev

SQL中的重叠日期