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