艾伦';SQL中的s区间代数运算

艾伦';SQL中的s区间代数运算,sql,algorithm,plsql,oracle11g,intervals,Sql,Algorithm,Plsql,Oracle11g,Intervals,我一直在努力解决SQL中的一些棘手问题,在这些问题中,我需要从事件间隔推断资产利用率,并且刚刚了解到,这似乎是解决这些问题的关键 代数描述了区间之间的13种关系,下图显示了前七种关系,其余为逆关系(即x之前的y,y与x相交,等等) 但我很难找到如何实施相关操作的方法 给定我的示例数据,如何在SQL或PLSQL中从以下三种类型的操作中获得结果 分离 减少 查找差距 请查看我的SQLFiddle链接: 原始数据 操作1-分离结果 我想要一个查询,从上面的数据返回不相交集,其中所有重叠的间隔

我一直在努力解决SQL中的一些棘手问题,在这些问题中,我需要从事件间隔推断资产利用率,并且刚刚了解到,这似乎是解决这些问题的关键

代数描述了区间之间的13种关系,下图显示了前七种关系,其余为逆关系(即x之前的y,y与x相交,等等)

但我很难找到如何实施相关操作的方法

给定我的示例数据,如何在SQL或PLSQL中从以下三种类型的操作中获得结果

  • 分离
  • 减少
  • 查找差距

  • 请查看我的SQLFiddle链接:


    原始数据


    操作1-分离结果 我想要一个查询,从上面的数据返回
    不相交集
    ,其中所有重叠的间隔都被分成了行,这样就不存在重叠

    我如何处理这个SQL

         start end width
    [1]      1   7     7
    [2]      8  12     5
    [3]     13  13     1
    [4]     14  14     1
    [5]     15  18     4
    [6]     19  19     1
    [7]     20  24     5
    [8]     25  29     5
    [9]     34  35     2
    [10]    40  46     7
    


    操作2-减少结果 我如何减少/平展间隔,以便:

    • 不为空(即它们具有非空宽度)
    • 不重叠
    • 从左到右排列
    • 甚至不相邻(即,两个连续范围之间必须存在非空间隙)
    以我为例,这看起来像:

        start end width
    [1]     1  29    29
    [2]    34  35     2
    [3]    40  46     7
    


    操作3-间隙结果 还有,我如何找到差距

       start end width
    [1]    30  33     4
    [2]    36  39     4
    
    这里有一个 首先,创建临时表以简化查询,但您可以将这些创建查询放入最终查询中,而不使用临时表:

    create table t as select * from
    (
    select null s ,"start"-1 as e  from data
    union all
    select "start" s,null e  from data
    union all
    select "end"+1 s ,null e  from data
    union all
    select null s ,"end" e  from data
    ) d where exists (select "start" 
                      from data where d.s between data."start" and data."end"
                                   or d.e between data."start" and data."end"
                                    );
    --Operation 1 - Disjoined Result   
    create table t1 as select s,e,e-s+1 width from
    (
    select distinct s,(select min(e) from t where t.e>=t1.s) e from t t1
    ) t2 where t2.s is not null and t2.e is not null;
    
    --Operation 2 - Reduced Result
    create table t2 as 
    select s,e,e-s+1 width from
    (
    select s,(select min(d2.e) from t1 d2 where d2.s>=d.s and not exists
              (select s from t1 where t1.s=d2.e+1) ) e
    from
    t1 d where not exists(select s from t1 where t1.e=d.s-1) 
    ) t2;
    
    --Temp table for Operation 3 - Gaps
    create table t3 as 
    select null s, s-1 e from t2
    union all
    select e+1 s, null e from t2;
    
    下面是一些问题:

    --Operation 1 - Disjoined Result
    select * from t1 order by s;
    
    --Operation 2 - Reduced Result
    
    
    select * from t2 order by s;
    
    --Operation 3 - Gaps
    
    select s,e,e-s+1 width 
    from
    (
    select s,(select min(e) from t3 where t3.e>=d.s) e from t3 d
    ) t4 where s is not null and e is not null
    order by s;
    
    --Operation 1 - Disjoined Result
    select * from t1 order by s;
    
    --Operation 2 - Reduced Result
    
    
    select * from t2 order by s;
    
    --Operation 3 - Gaps
    
    select s,e,e-s+1 width 
    from
    (
    select s,(select min(e) from t3 where t3.e>=d.s) e from t3 d
    ) t4 where s is not null and e is not null
    order by s;