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
 SQL Server Development (2000)
 Unusual Concatenation

Author  Topic 

bdennis
Starting Member

4 Posts

Posted - 2004-07-01 : 11:10:42
here's the deal... I have a table that contains unique record numbers, origin cities, destination cities, and segment numbers for a trip. Allow me to clarify with a table:

+--------------------------------------------+
| UID SegmentNum OriginCity DestCity |
+============================================+
| 1 1 Dallas Houston |
| 1 2 Houston New York |
| 1 3 New York Dallas |
| 2 1 Las Angeles Seattle |
| 2 2 Seattle Las Angeles |
+--------------------------------------------+

...so, for the trip identified by UID=1, we would be flying from:
Dallas to Houston, then
Houston to New York, and finally
New York back to Dallas

...and for the trip identified by UID=2, we would be flying from:
Las Angeles to Seattle, and then
Seattle to Las Angeles

(both of the trips are round-trip).
What I need to do is create a string with the routing codes for each trip in the table. My result-set would look like the following:

+-----------------------------------------+
| UID RoutingCodes |
+=========================================+
| 1 Dallas/Houston/New York/Dallas |
| 2 Las Angeles/Seattle/Las Angeles |
+-----------------------------------------+

Right now, I can create the routing codes for a *single* trip (i.e. 'Dallas/Houston/New York/Dallas') with a few select statements and variables. However, I cannot create the whole result-set (both trips) without using some kind of loop or cursor. Can anyone suggest a way to achieve this without a loop/cursor (and without using temp-tables)? Any assistance would be greatly appreciated.

-Blake

Wanderer
Master Smack Fu Yak Hacker

1168 Posts

Posted - 2004-07-01 : 11:29:09
Hmm - you could post your current SQL, and table structures (data types incl)?

*##* *##* *##* *##*

Chaos, Disorder and Panic ... my work is done here!
Go to Top of Page

bdennis
Starting Member

4 Posts

Posted - 2004-07-01 : 11:47:05
The TripInfo table structure is as follows:

UID - VarChar(20)
SegmentNum - Int
OriginCity - VarChar(20)
DestCity - VarChar(20)

...UID and SegmentNum makeup the primary key.

The SQL I'm using to generate a routing-string for a trip looks like the following:

-- This will hold our routing-string:
DECLARE @RoutingCode VarChar(300)
-- This is a variable I use to specify a trip:
DECLARE @RecordKey VarChar(20)

-- This is just an arbitrary UID for a trip:
SET @RecordKey = '1'

-- First we select the OriginCity of the first segment...
SELECT @RoutingCode = a.OriginCity
FROM TripInfo a
WHERE a.UID = @RecordKey
AND a.SegmentNum = 1

-- Now we append each DestCity of ALL of the segments (including the first)
SELECT @RoutingCode = @RoutingCode + '/' + a.DestCity
FROM TripInfo a
WHERE a.UID = @RecordKey
ORDER BY a.SegmentNum

-- Display the routing-string:
SELECT @RoutingCode


...and that code would generate the following route-string for the trip identified by UID='1' in the tables on my first post:
'Dallas/Houston/New York/Dallas'

any ideas?
Go to Top of Page

ehorn
Master Smack Fu Yak Hacker

1632 Posts

Posted - 2004-07-01 : 21:10:45
The following is a technique which can be reviewed at the following link:
http://www.sqlteam.com/item.asp?ItemID=11021

create table route ( UID int,SegmentNum int, OriginCity varchar(30), DestCity varchar(30) )

insert into route
select 1, 1, 'Dallas' ,'Houston' union all
select 1, 2, 'Houston' ,'New York' union all
select 1, 3, 'New York' ,'Dallas' union all
select 2, 1, 'Las Angeles' ,'Seattle' union all
select 2, 2, 'Seattle' ,'Las Angeles'


select r.uid,segmentnum, origincity,destcity,d.max_seg, replicate(' ',1000) as trip_route
into #route
from route r
join
(
select uid, max(segmentnum) as max_seg
from route
group by uid
) d on d.uid = r.uid
order by r.uid, r.segmentnum

declare @uid int,@max_seg int,@route varchar(1000)
select @uid = 0, @route = '', @max_seg=0

update #route set @route = trip_route =
case
when uid <> @uid then origincity
when uid = @uid and @max_seg > segmentnum then @route + '/' + origincity + '/'
when uid = @uid and @max_seg = segmentnum then @route + origincity + '/' + destcity
else origincity
end,
@max_seg = max_seg,
@uid = uid

select uid,max(trip_route)
from #route
group by uid

drop table route, #route
Go to Top of Page

bdennis
Starting Member

4 Posts

Posted - 2004-07-02 : 08:06:08
thanks for the post... I was trying to stay away from temp tables for speed reasons, but the more I study over it, the more I think temp tables may be a necessecity in this situation...

any other ideas?
Go to Top of Page

kselvia
Aged Yak Warrior

526 Posts

Posted - 2004-07-02 : 13:34:17
You can do it with a loop, table variable, dynamic SQL, or complex correlated subqueries but none are as efficient as ehorn's solution. I actually did it and tested them but they sucked comparatively.
Go to Top of Page

ehorn
Master Smack Fu Yak Hacker

1632 Posts

Posted - 2004-07-02 : 13:46:55
quote:
Originally posted by kselvia

You can do it with a loop, table variable, dynamic SQL, or complex correlated subqueries but none are as efficient as ehorn's solution. I actually did it and tested them but they sucked comparatively.

The only solution which is more efficient is described by Byrmol (uses a udf) in the comments section of the article I included in my post. It is a very good read for those interested.
Go to Top of Page

Seventhnight
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2004-07-02 : 13:47:01
Now see thats just nice... haven't thought of it that way...

So many new things!! Must Remember!!

Corey
Go to Top of Page

bdennis
Starting Member

4 Posts

Posted - 2004-07-02 : 14:34:13
udf is more efficient that a temp table? then a udf it shall be! thanks for the help!
Go to Top of Page

Seventhnight
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2004-07-02 : 14:48:11
simplified I believe....

thanks to ehorn:

Create function dbo.getRoute
(
@UId int
)
Returns nvarchar(1000) As
Begin
Declare @fullRoute nvarchar(1000)

Select @fullRoute = isnull(@fullRoute,OriginCity) + '/' + DestCity
From route
Where UId = @UId
Order By SegmentNum

Return @fullRoute
End
Go

create table route ( UID int,SegmentNum int, OriginCity varchar(30), DestCity varchar(30) )

insert into route
select 1, 1, 'Dallas' ,'Houston' union all
select 1, 2, 'Houston' ,'New York' union all
select 1, 3, 'New York' ,'Dallas' union all
select 2, 1, 'Las Angeles' ,'Seattle' union all
select 2, 2, 'Seattle' ,'Las Angeles'
Go

select
Distinct
uid,
trip_Route = dbo.getRoute(uid)
from route


drop table route
drop function dbo.getRoute



Corey
Go to Top of Page
   

- Advertisement -