MS SQL 2005/2008 solution. Will not work on MS SQL 2000.
create table #journeySegment (make varchar(100) not null
, model varchar(100) not null
, distanceFrom decimal(10,2) not null
, distanceTo decimal(10, 2) not null
, driverId int not null -- References blah
, CONSTRAINT data_U unique (make, model, driverId, distanceFrom)
, CONSTRAINT data_FromTo_CHK check (distanceFrom <= distanceTo))
insert into #journeySegment values ('toyota', 'yaris', 358.2, 368.2, 401)
insert into #journeySegment values ('toyota', 'yaris', 368.2, 378.7, 103)
insert into #journeySegment values ('toyota', 'yaris', 378.7, 382.2, 103)
insert into #journeySegment values ('toyota', 'yaris', 382.2, 392.2, 103)
insert into #journeySegment values ('toyota', 'yaris', 392.2, 403.6, 103)
insert into #journeySegment values ('toyota', 'yaris', 403.6, 414.3, 103)
insert into #journeySegment values ('toyota', 'yaris', 414.3, 419.4, 103)
insert into #journeySegment values ('toyota', 'yaris', 419.4, 430.2, 103)
insert into #journeySegment values ('toyota', 'yaris', 430.2, 439.2, 401)
insert into #journeySegment values ('toyota', 'yaris', 439.2, 446, 401)
insert into #journeySegment values ('toyota', 'yaris', 446, 457.2, 401)
insert into #journeySegment values ('toyota', 'yaris', 457.2, 460.1, 401)
insert into #journeySegment values ('toyota', 'yaris', 460.1, 468.6, 401)
insert into #journeySegment values ('toyota', 'yaris', 468.6, 480.3, 401)
insert into #journeySegment values ('toyota', 'yaris', 480.3, 486.2, 103)
insert into #journeySegment values ('toyota', 'yaris', 486.2, 490, 103)
insert into #journeySegment values ('toyota', 'yaris', 490, 501.1, 103)
insert into #journeySegment values ('toyota', 'yaris', 501.1, 512.5, 103)
insert into #journeySegment values ('toyota', 'yaris', 512.5, 523.1, 103)
insert into #journeySegment values ('toyota', 'yaris', 523.1, 532.6, 513)
insert into #journeySegment values ('toyota', 'yaris', 532.6, 542.7, 513)
insert into #journeySegment values ('toyota', 'yaris', 542.7, 551.1, 513)
-- ASSUMPTIONS:
-- journeySegments do not overlap.
-- distanceFrom and distanceTo are exact numeric types.
; with potentialJourney (make, model, journeyFrom, journeyTo, driverId, level) as
(-- Find the starting segment for each journey.
select make,
model,
distanceFrom,
distanceTo,
driverId,
0
from #journeySegment A
where not exists
(select *
from #journeySegment B
where B.make = A.Make
and B.model = A.model
and B.driverId = A.driverId
and B.DistanceTo = A.DistanceFrom)
union all
-- add on next segment.
select PJ.make
, PJ.model
, PJ.journeyFrom
, nextJS.distanceTo
, PJ.driverId
, PJ.level + 1
from potentialJourney PJ
inner join #journeySegment nextJS
on nextJS.make = PJ.Make
and nextJS.model = PJ.Model
and nextJs.driverId = PJ.driverId
and nextJs.distanceFrom = PJ.journeyTo)
select M.make
, M.Model
, M.journeyFrom
, M.journeyTo
, M.driverId
from potentialJourney M
-- Eliminate the partial solutions
where not exists
(select *
from potentialJourney S
where S.make = M.make
and S.model = M.model
and S.journeyFrom = M.journeyFrom
and S.driverId = M.driverId
and S.level > M.level)
order by journeyFrom