Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 Transact-SQL (2000)
 Identifying Overlapping Records

Author  Topic 

AskSQLTeam
Ask SQLTeam Question

0 Posts

Posted - 2005-02-16 : 08:17:58
Stuart writes "I have a set of data which contains overlapping values:

ID Min Max
10 400 500
20 350 470
30 480 520
40 460 540
50 310 360

I am happy with determining which rows overlap with the others by joining the table to itself, but what I am trying to establish is which records are redundant because their range is covered by a later entry.

In other words, it is akin to shadows projected onto a background. If ID=10 is my background, I want to find which other records would be visible on it.

Moving from back to front:

10 is visible in the range 400-500
20 is visible in the range 400-470, partially obscures 10
30 is visible in the range 480-500, partially obscures 10
40 is visible in the range 460-500, partially obscures 20 and completely obscures 30
50 is not visible in the range.

The answer I want to get is

Base ID Min Max
10 20 400 460
10 40 460 500

I know an algorithmic solution can be coded, but can it be done in SQL?"

TG
Master Smack Fu Yak Hacker

6065 Posts

Posted - 2005-02-16 : 13:24:45
Truly Wacky! What the heck are you using this for? Anyway, I THINK this will do it:

set nocount on
Declare @tb Table ([id] int, [min] int, [max] int)
insert @tb
Select 10, 400, 500 UNION ALL
SElect 20, 350, 470 UNION ALL
Select 30, 480, 520 UNION ALL
Select 40, 460, 540 UNION ALL
Select 50, 310, 360


Select base = bg.[id]
,a.[id]
,[min] = case when a.[min] < bg.[min] then bg.[min] else a.[min] end
,[max] = case when a.[max] < bg.[max] then a.[max] else bg.[max] end
From
--Get the background record
(SElect [id], [min], [max] from @tb where [id] = (Select min([id]) from @tb)) bg

JOIN @tb a
--limit results to ranges that overlap the background
ON bg.[min] <= a.[max] AND bg.[max] >= a.[min]

Left JOIN (--Get all previous records that are completely obsured by current record
Select y.[id]
From @tb z
JOIN @tb y
ON --only previous records
y.[id] < z.[id]
AND
--only records completely obscured
y.[min] >= z.[min] AND y.[max] <= z.[max]
) as obscured
ON a.[id] = obscured.[id]

--exclude the background record from results
Where a.[id] <> bg.[id]

--exlcude previous completely obscured records
AND obscured.[id] is NULL


Be One with the Optimizer
TG
Go to Top of Page
   

- Advertisement -