【问题标题】:SQL Recursive CTE alternativeSQL 递归 CTE 替代方案
【发布时间】:2018-01-04 19:28:00
【问题描述】:

我的任务是在 Redshift 中合并重叠的时间范围。

这是一个很好的解决方案: Merge overlapping time intervals, how?

很遗憾,Redshift 不支持递归 CTE。如何转换此代码以在不递归的情况下执行它?

WITH RECURSIVE cte( id, date_start, date_end ) AS
(
  SELECT id, date_start, date_end
  FROM evento
  UNION 
  SELECT e.id,
         least( c.date_start, e.date_start ),
         greatest( c.date_end, e.date_end )
  FROM cte c
  JOIN evento e
  ON e.date_start between c.date_start and c.date_end
     OR 
     e.date_end between c.date_start and c.date_end
)
SELECT distinct date_start, date_end
FROM (
  SELECT id, 
         min( date_start) date_start, 
         max( date_end ) date_end
  FROM cte
  GROUP BY id
) xx
ORDER BY date_start;

http://www.sqlfiddle.com/#!12/bdf7e/9

【问题讨论】:

    标签: sql amazon-redshift hierarchical-data recursive-query


    【解决方案1】:

    您可以将日期与之前的行日期进行比较,并使用累积和构建段 ID,如下所示:

    WITH
    prev_dates as (
        select id, date_start, date_end,
        lag(date_end) over (order by date_start) as prev_date_end
        from evento
    ),
    sequences as (
        select *,
        sum(case when date_start>prev_date_end then 1 else 0 end) over (order by date_start) as sequence_id
        from prev_dates   
    )
    select 
    sequence_id,
    min(date_start) as date_stat,
    max(date_end) as date_end
    from sequences
    group by 1
    

    【讨论】:

    • 感谢您的回答,亚历克斯。抱歉,我在我的问题中错过了“在线”或“忙碌”状态的类型列。因此,一个 Online 会话中可以有 1 个或多个 Busy 会话,我们应该将 date_start 与 prev Online-date-end 进行比较。如何在窗口函数中考虑这个?
    • 是“在线”会话中的“忙碌”会话,您需要确定“在线”会话的顺序吗?
    • 一些“忙碌”的会话不在“在线”范围内。这是数据的错误,我想填补出现“忙碌”的“在线”时间的空白。
    • @Dmitros 如果“忙碌”会话被链接,您只能通过按状态过滤记录来构建“忙碌”会话序列,然后将这些序列合并到“在线”会话并执行相同的排序操作。 ..有意义吗?
    【解决方案2】:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-17
    相关资源
    最近更新 更多