【问题标题】:Time interval overlaps - teradata时间间隔重叠 - teradata
【发布时间】:2013-07-30 11:56:29
【问题描述】:

我需要有关间隔重叠的帮助。我在一张表中有这些记录(还有更多):

示例 1:

Id---------StartDate------EndDate

794122    2011-05-10    2999-12-31

794122    2011-04-15    2999-12-31

794122    2008-04-03    2999-12-31

794122    2008-03-31    2999-12-31

794122    2008-02-29    2999-12-31

794122    2008-02-04    2999-12-31

794122    2007-10-10    2999-12-31

794122    2007-09-15    2999-12-31

示例 2:

Id---------StartDate------EndDate

5448    2012-12-28      2999-12-31

5448    2011-06-30      2999-12-31

5448    2005-12-26      2011-06-30

5448    2005-06-15      2011-06-30

5448    2006-07-31      2006-12-31

5448    2001-03-31      2006-07-15

示例 3:

Id---------StartDate------EndDate

214577    2007-02-28    2999-12-31

214577    2003-06-20    2007-03-04

214577    2003-06-20    2007-02-28

示例 4:

Id---------StartDate-------EndDate

9999    2008-05-28      2999-01-01

9999    2005-03-03      2008-05-31

9999    2005-05-31      2005-12-31

9999    2003-12-01      2005-08-12

9999    2001-01-01      2002-03-05

9999    2000-01-08      2002-01-01

我想得到:

*Example1* - 2007-09-15->3000-01-01

*Example2* - 2001-03-31->3000-01-01

*Example3* - 2003-06-20->3000-01-01

*Example4* - 2003-12-01->3000-01-01

你有什么建议吗?因为我没有选择最大值和最小值(按 Id 分组)-> 这个问题在示例 4 中。

谢谢!

【问题讨论】:

  • 您的问题是什么?你能显示你想要的结果吗?
  • 我想获得以下时间间隔:Example1 - 2007-09-15->3000-01-01 Example2 - 2001-03-31->3000-01-01 Example3 - 2003-06 -20->3000-01-01 Example4 - 2003-12-01->3000-01-01 !!!
  • 这是错字吗? {9999, 2008-05-28, 2999-01-01}
  • 例4中选择2003年开始日期的逻辑是什么?
  • 对不起,迈克,我在示例 4 中犯了错误。现在可以了。我要不间断的间隔。

标签: sql teradata


【解决方案1】:

例如 #4 的结果与您的数据不匹配,这不应该是 9999、2999-01-02 而不是 3000-01-01 吗?

组合重叠时段的典型解决方案使用嵌套的 OLAP 函数,针对您的特定要求(仅限最新时段),可以将其简化为:

SELECT *
FROM
 (
   SELECT DISTINCT -- DISTINCT is not neccessary, but results in a better plan
      Id,
      StartDate,
      MAX(EndDate) 
      OVER (PARTITION BY Id) + 1 AS EndDate
   FROM dropme AS t
   QUALIFY -- find the gap
      COALESCE(StartDate 
               - MAX(EndDate) 
                 OVER (PARTITION BY Id
                       ORDER BY StartDate, EndDate
                       ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING), 1) > 0
 ) AS dt
QUALIFY 
   ROW_NUMBER() 
   OVER (PARTITION BY Id
         ORDER BY StartDate DESC) = 1
;

【讨论】:

    【解决方案2】:

    您希望结束日期为下一年的第一天?

    select id, min(startdate) start_date, 
           cast(max(extract(year from enddate)) + 1 || '-01-01' as date) end_date
    from table1
    group by id
    

    【讨论】:

    • 谢谢,但我想要不间断的间隔。我总是从 max enddate 开始并搜索它。
    【解决方案3】:

    你只是想这样做吗?

    select id, min(start_date) as start_date, max(end_date) as end_date
    from t
    group by id;
    

    编辑:

    现在我明白你需要什么了。它标识开始新周期的行(使用not exists 子句查找重叠)。然后它为每个 id 在这些行中选择最大的 start_date

    select t.id, min(t.start_date) as start_date, max(t.end_date) as end_date
    from (select id, max(start_date) as maxsd
          from t
          where not exists (select 1
                            from t t2
                            where t2.start_date < t.start_date and
                                  t2.end_date >= t.start_date
                           )
          group by id
         ) ids join
         t
         on t.id = ids.id and
            t.start_date >= maxsd
    group by t.id;
    

    最后一步连接回原始数据,并对开始日期之后开始的任何数据进行聚合。

    【讨论】:

    • 谢谢,但它在示例 4 中不起作用(我需要 2003-12-01->3000-01-01)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-08
    • 2019-08-12
    • 1970-01-01
    • 1970-01-01
    • 2019-04-12
    • 2019-12-12
    相关资源
    最近更新 更多