Reputation: 2318
Let's say I have a column Address
Address
NYC, NY State, USA
London, xxx, England
I want to swap the chars before and after the first delimiter ','.
The desired output is
Address
NY State, NYC, USA
xxx, London, England
I think substring
or charindex
may help, but I am not sure how.
Upvotes: 0
Views: 119
Reputation: 25112
Using PARSENAME
declare @table table (addy varchar(64))
insert into @table
values
('NYC, NY State, USA'),
('London, xxx, England'),
('Missouri, St. Louis, USA')
select
replace(
parsename(replace(replace(addy,'.','^'),',','.'),2)
+ ', '
+ parsename(replace(replace(addy,'.','^'),',','.'),3)
+ ', '
+ parsename(replace(replace(addy,'.','^'),',','.'),1)
,'^','.')
from @table
This is a common function to break up strings by a delimiter when there are 4 or lesser parts. In your case, 3. We simply need to replace the comma with a period. (and use a hyphen or something for when there should be a period)
STUFF
, RIGHT
, LEN
, a couple other string manipulations.
select
stuff(right(addy,len(addy) - charindex(',',addy)),charindex(',',right(addy,len(addy) - charindex(',',addy))),0, ', ' + substring(addy,0,CHARINDEX(',',addy)) )
from @table
First we get everything up the first comma:
substring(addy,0,CHARINDEX(',',addy))
Then, we find everything after the first comma:
right(addy,len(addy) - charindex(',',addy))
Finally, we combined these to subsets of your string with STUFF
for insert the first part, into the second part, starting at the comma.
stuff(right(addy,len(addy) - charindex(',',addy)),charindex(',',right(addy,len(addy) - charindex(',',addy))),0, ', ' + substring(addy,0,CHARINDEX(',',addy)) )
Upvotes: 2
Reputation: 81930
Perhaps another option
Example
Declare @YourTable table (ID int,[Address] varchar(150))
Insert Into @YourTable values
(1,'NYC, NY State, USA')
,(2,'London, xxx, England')
Select A.ID
,NewString = concat(Pos2,', '+Pos1,', '+Pos3)
From @YourTable A
Cross Apply (
Select Pos1 = n.value('/x[1]','varchar(max)')
,Pos2 = n.value('/x[2]','varchar(max)')
,Pos3 = n.value('/x[3]','varchar(max)')
From (Select cast('<x>' + replace([Address],',','</x><x>')+'</x>' as xml) as n) X
) B
Returns
ID NewString
1 NY State, NYC, USA
2 xxx, London, England
Upvotes: 2
Reputation: 95554
If you want to do this without using a String Spliter, then the following would work (provided the address is split into 3 parts):
WITH VTE AS(
SELECT *
FROM (VALUES('NYC, NY State, USA'),
('London, xxx, England')) V([Address]))
SELECT V.[Address],
SUBSTRING([Address], CI1.CI +1, CI2.CI-CI1.CI) + LEFT(V.[Address], CI1.CI) + RIGHT(V.[Address], LEN(V.[Address]) - CI2.CI)
FROM VTE V
CROSS APPLY(VALUES(CHARINDEX(',',V.[Address]))) CI1(CI)
CROSS APPLY(VALUES(CHARINDEX(',',V.[Address], CI1.CI + 1))) CI2(CI);
If, however, you can use a splitter which provides to ordinal position (for example delimitedsplit8k
), you can do something like this:
USE Sandbox;
Go
WITH VTE AS(
SELECT *
FROM (VALUES('NYC, NY State, USA'),
('London, xxx, England')) V([Address]))
SELECT V.[Address],
STUFF((SELECT ',' + item
FROM dbo.DelimitedSplit8K(V.[Address],',') DS
ORDER BY CASE DS.ItemNumber WHEN 1 THEN 2
WHEN 2 THEN 1
ELSE DS.ItemNumber END
FOR XML PATH('')),1,1,'')
FROM VTE V;
Upvotes: 0