- This task is based on the actual practice of using IP ranges.
- The solution I came up with is based on the stack trace problem I introduced earlier. Each range start is treated as a PUSH operation, and each end of range + 1 is treated as a POP operation.
Task
We have a range data set, where each range has a start point, end point and value.
create table ranges ( range_start int not null ,range_end int not null ,range_val char(1) not null ) ;
A range may contain a different range or follow a different range, but may not be equal to another range or intersect with another range.
These are valid relationships between ranges:
(1) (2) (3) (4)
This relationship is not valid :
(5) (6)
Our initial ranges, if presented graphically, might look something like this (the letter represents range_val ):
AAAAAAAA BBCCCCCCC DDE F GGGGG H IIII J
The goal is to take the original range set and create a new set according to the following rule:
A held range will override the corresponding sub-range of the containing range.
The requested result, if presented graphically, might look something like this.
ADDHAAAF BIIJIGCCC
Requirements
- The solution should be the only SQL query (subqueries in order).
- Using T-SQL, PL / SQL, etc. not allowed .
- The use of UDF (Custom Functions) is not permitted .
Sample data
AAAAAAAAAAAAAAAAAAAAAAAAAAAA BBBB CCCCCCCCCCCCCCCCCCCCCCCCC DDDE FFFFFFFF GGGGGGGGG HHHHHHHH IIIIIII JJ KKKLLL MM NN OOOOO P QQ insert into ranges (range_start,range_end,range_val) values (1 ,28 ,'A'); insert into ranges (range_start,range_end,range_val) values (31 ,34 ,'B'); insert into ranges (range_start,range_end,range_val) values (39 ,63 ,'C'); insert into ranges (range_start,range_end,range_val) values (1 ,3 ,'D'); insert into ranges (range_start,range_end,range_val) values (4 ,4 ,'E'); insert into ranges (range_start,range_end,range_val) values (7 ,14 ,'F'); insert into ranges (range_start,range_end,range_val) values (19 ,27 ,'G'); insert into ranges (range_start,range_end,range_val) values (43 ,50 ,'H'); insert into ranges (range_start,range_end,range_val) values (55 ,61 ,'I'); insert into ranges (range_start,range_end,range_val) values (1 ,2 ,'J'); insert into ranges (range_start,range_end,range_val) values (9 ,11 ,'K'); insert into ranges (range_start,range_end,range_val) values (12 ,14 ,'L'); insert into ranges (range_start,range_end,range_val) values (22 ,23 ,'M'); insert into ranges (range_start,range_end,range_val) values (25 ,26 ,'N'); insert into ranges (range_start,range_end,range_val) values (57 ,61 ,'O'); insert into ranges (range_start,range_end,range_val) values (13 ,13 ,'P'); insert into ranges (range_start,range_end,range_val) values (60 ,61 ,'Q');
Requested results
(Zeros are represented here as empty spaces)
JJDEAAFFKKKLPLAAAAGGGMMGNNGA BBBB CCCCHHHHHHHHCCCCIIOOOQQCC range_start range_end range_val
Additional optional final line:
64