April 6, 2012 at 11:58 am
hi, i have a table with two columns:
1)StopName
2)Distance_to_next_stop
i would like to end up with a table with 3 columns:
1)FromStop
2)ToStop
3)Distance
the records should be (assuming a table with 4 stops in it):
Distance from Stop A to Stop B
Distance from Stop A to Stop C
Distance from Stop A to Stop D
Distance from Stop B to Stop C
Distance from Stop B to Stop D
Distance from Stop C to Stop D
I hope i explained this adequately, thanks for any help given.
-mm
April 6, 2012 at 12:05 pm
I'm confident this can be done without a loop.
Please read the first article in my signature and post table def and sample data in a ready to use format so we have something to work with. In return you'll get a tested solution based on your sample data.
April 6, 2012 at 12:09 pm
Self join would do it meaning, you have to join your table with itself, apply your logic.
_____________________________________
Pablo (Paul) Berzukov
Author of Understanding Database Administration available at Amazon and other bookstores.
Disclaimer: Advice is provided to the best of my knowledge but no implicit or explicit warranties are provided. Since the advisor explicitly encourages testing any and all suggestions on a test non-production environment advisor should not held liable or responsible for any actions taken based on the given advice.April 6, 2012 at 12:18 pm
Thanks for the advice mr. lutzm. my logic fails me on this one...
ok here's a table and sample data:
CREATE TABLE [dbo].[distancetest1](
[StopName] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[dist] [numeric](3, 1) NULL
) ON [PRIMARY]
INSERT INTO DISTANCETEST1 (StopName, dist)
select 'A', '3.5' UNION ALL
select 'B', '2.3' UNION ALL
Select 'C', '1.7' UNION ALL
Select 'D', '3.0'
The results would show 6 rows:
A to B, Distance,
A to C, Distance,
A to D, Distance,
B to C, Distance,
B to D, Distance,
C to D, Distance
thanks again, guys.
April 6, 2012 at 12:51 pm
Whats the logic to find the distance betwen A and C ? is it ( A to B ) + (A to C) or is it value of distance in A + value of distance in C?
April 6, 2012 at 12:51 pm
Can you give the expected results based on your sample data? You have given a skelton of the desired result, but can u populate the expected results with the values from your sample data?
April 6, 2012 at 1:01 pm
yes sir, here would be the result table:
CREATE TABLE [dbo].[distancetest2](
[FromStop] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[ToStop] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[dist] [numeric](3, 1) NULL
) ON [PRIMARY]
INSERT INTO DISTANCETEST2 (FromStop, ToStop, dist)
select 'A','B', '3.5' UNION ALL
select 'A','C', '5.8' UNION ALL
Select 'A','D', '7.5' UNION ALL
Select 'B','C', '2.3' UNION ALL
Select 'B','D', '4.0' UNION ALL
Select 'C','D', '1.7'
thanks again for any help
April 6, 2012 at 1:18 pm
ColdCoffee (4/6/2012)
Whats the logic to find the distance betwen A and C ? is it ( A to B ) + (A to C) or is it value of distance in A + value of distance in C?
the answer to this would be (A to B) + (B to C)
April 6, 2012 at 1:53 pm
How about this?
; WITH CTE AS
(
SELECT RN = ROW_NUMBER() OVER(ORDER BY DST.StopName) , DST.StopName, DST.dist
FROM distancetest1 DST
)
,ListOfStops AS
(
SELECT FromStop = OutQ.StopName
, ToStop = CrsApp.StopName
FROM CTEOutQ
CROSS APPLY
(
SELECT InrQr.StopName
FROM CTE InrQr
WHERE InrQr.RN > OutQ.RN
) CrsApp
)
SELECT Los.FromStop
,LoS.ToStop
,SUM(Base.dist) AS dist
FROM ListOfStops LoS
LEFT JOIN distancetest1 Base
ON Base.StopName >= LoS.FromStop AND Base.StopName < LoS.ToStop
GROUP BY Los.FromStop
,LoS.ToStop
ORDER BY Los.FromStop
,LoS.ToStop
I guess on a million-plus table, this is going to suck 🙁 let me check of another solution and another idea altogether!
April 6, 2012 at 1:53 pm
This solution depends on the StopName being ascending as shown in your sample data.
If that's not the case, you'll need to use another column that define whether a stop belongs to a route or not.
SELECT
d1.StopName AS FromStop,
d2.StopName AS ToStop,
t.dist
FROM #distancetest1 d1
INNER JOIN #distancetest1 d2 ON d1.StopName < d2.StopName
CROSS APPLY
(
SELECT
SUM(dist) dist
FROM #distancetest1 d3
WHERE
d3.StopName >= d1.StopName
AND d3.StopName < d2.StopName
) t
ORDER BY d1.StopName
April 6, 2012 at 1:59 pm
wow, that works, i just have to decipher it now!
you're a genius, if you were a guitar player you'd be jimi hendrix...
the datasets are usually going to be really small (less than 40 records), so this solution is OK.
However, i won't stop you from coming up with variations, more things i can learn.
thanks!!
April 6, 2012 at 2:04 pm
i wish i had a fraction of your intellect...
thanks for taking the time to answer my question, i learned a new thing today!
-mm
Viewing 12 posts - 1 through 11 (of 11 total)
You must be logged in to reply to this topic. Login to reply