I've been struggling to solve a few tricky problems in SQL where I need to infer asset utilisation from event intervals, and have just learned about Allen's Interval Algebra, which seems to be the key to solving these problems.
The algebra describes 13 kinds of relationships between intervals, and the image below shows the first seven, with the rest being the inverse (i.e. y before x, y meets x, etc)
But I'm having trouble finding out how to implement the relevant operations.
Given my sample data, how can I go about getting results from the following three types of operations in SQL or PLSQL?
- Disjoin
- Reduce
- Find Gaps
Please see my SQLFiddle link: http://sqlfiddle.com/#!4/cf0cc
Original Data
start end width
[1] 1 12 12
[2] 8 13 6
[3] 14 19 6
[4] 15 29 15
[5] 19 24 6
[6] 34 35 2
[7] 40 46 7
Operation 1 - Disjoined Result
I'd like a query to return the disjoint set
from the data above, where all overlapping intervals have been broken into rows such that no overlaps exist.
How do I go about this 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
Operation 2 - Reduced Result
How do I go about reducing/flattening the intervals, such that they are:
- not empty (i.e. they have a non-null width);
- not overlapping;
- ordered from left to right;
- not even adjacent (i.e. there must be a non empty gap between 2 consecutive ranges)
For my example, this would look like:
start end width
[1] 1 29 29
[2] 34 35 2
[3] 40 46 7
Operation 3 - Gap Result
Also, how would I find the gaps?
start end width
[1] 30 33 4
[2] 36 39 4