Reputation: 7289
I need to update the url stored in a column.
My columns have values like this:
https://www.site.sharepoint.com/sites/test/AB-19-CALL
I want to update this URL to:
https://www.site.sharepoint.com/sites/test/CALL-AB-19
To get the last part which is AB-19-CALL
, I used the below query
SELECT
SUBSTRING(urlcompte, LEN(urlcompte) - CHARINDEX('/', REVERSE(urlcompte)) + 2, LEN(urlcompte)),
UrlCompte
FROM
tblAccount
Now to split and reverse the AB-19-call
I would again need to use the entire query above and then select substring using -
Is there an easier way to do this?
In C# we can do something like this:
urlCompte.Split('-')[2] + urlCompte.Split('-')[0] + urlCompte.Split('-')[1]
Is there a way in SQL Server to split the column and access different parts of it?
Upvotes: 3
Views: 2163
Reputation: 6656
Well, this is the xml based solution. For SQL Server 2008 and above.
DECLARE @url VARCHAR(100) = 'AB-19-CALL'
SELECT MyUrl FROM
(
SELECT CAST('<Url><Part>' + REPLACE(@url,'-','</Part><Part>') + '</Part></Url>' AS XML) AS my_Xml
) t1
CROSS APPLY
(
SELECT
my_Data.D.value('Part[3]','varchar(50)') + '-' +
my_Data.D.value('Part[1]','varchar(50)') + '-' +
my_Data.D.value('Part[2]','varchar(50)') AS MyUrl
FROM t1.my_Xml.nodes('/Url') as my_Data(D)
) t2
Result
MyUrl
----------
CALL-AB-19
Upvotes: 1
Reputation: 2762
If someone is using SQL server 2012 or older version then it can be possible by this way:
DECLARE @URL VARCHAR(100) = 'https://www.site.sharepoint.com/sites/test/AB-19-CALL'
SELECT TOP 1 dbo.[Reversedata](DATA, '-')
FROM (SELECT * FROM dbo.Splitter(@URL, '/') as t) as tt order by Id desc
In above code I have used two functions: 1) Splitter : To split the string (https://ole.michelsen.dk/blog/split-string-to-table-using-transact-sql.html) 2) Reversedata: To reverse the data (http://picnicerror.net/development/sql-server/reverse-order-words-string-sql-server-2012-01-16/)
Splitter:
CREATE FUNCTION [dbo].[Splitter]
(
@String NVARCHAR(4000),
@Delimiter NCHAR(1)
)
RETURNS TABLE
AS
RETURN
(
WITH Split(stpos,endpos)
AS(
SELECT 0 AS stpos, CHARINDEX(@Delimiter,@String) AS endpos
UNION ALL
SELECT endpos+1, CHARINDEX(@Delimiter,@String,endpos+1)
FROM Split
WHERE endpos > 0
)
SELECT 'Id' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)),
'Data' = SUBSTRING(@String,stpos,COALESCE(NULLIF(endpos,0),LEN(@String)+1)-stpos)
FROM Split
)
GO
Reverse:
CREATE FUNCTION [dbo].[udf_ReverseSequenceOrder] (
@Input nvarchar(200)
,@Delimiter nvarchar(5)
)
RETURNS nvarchar(200)
AS
BEGIN
DECLARE @Output nvarchar(200)
WHILE LEN(@Input) > 0
BEGIN
IF CHARINDEX(@Delimiter, @Input) > 0
BEGIN
SET @Output = SUBSTRING(@Input,0,CHARINDEX(@Delimiter, @Input)) + @Delimiter + ISNULL(@Output,'')
SET @Input = SUBSTRING(@Input,CHARINDEX(@Delimiter, @Input)+1,LEN(@Input))
END
ELSE
BEGIN
SET @Output = @Input + @Delimiter + ISNULL(@Output,'')
SET @Input = ''
END
END
RETURN SUBSTRING(@Output,0,LEN(@Output))
END
Upvotes: 1
Reputation: 6612
If you are so lucky to be using SQL Server 2017 you can use for string_agg function for concatenating splitted string pieced with SQL string_split function
Here is the script to change the order of last part in your url
declare @url varchar(100) = 'CALL-AB-19'
select
string_agg(value,'-') within group (order by rn desc)
from (
select
value, row_number() over (order by @url) as rn
from STRING_SPLIT( @url , '-' )
) t
If you want to apply this solution as a set based solution on your table rows with a single SELECT statement, you can execute following SQL
select
id, string_agg(value,'-') within group (order by rn desc)
from (
select
id, value, row_number() over (partition by id order by url) as rn
from urlList
cross apply STRING_SPLIT( url , '-' )
) t
group by id
I assume, in your table urlList, you have a PK field id
If you don't use SQL Server 2016 for split function and SQL Server 2017 for string aggregate function, you can search the web for split string function samples. And using FOR XML Path to concatenate string parts, you can build a solution with the help of CTE expression as follows
;with cte as (
select
urlList.id,
urlList.url,
s.id sid,
s.val
from urlList
cross apply dbo.split(url,'-' ) s
)
SELECT
distinct
id,
STUFF(
(
SELECT
'-' + u.val
FROM cte as u
where u.id = cte.id
Order By sid desc
FOR XML PATH('')
), 1, 1, ''
) As newurl
FROM cte
Please note that the referred split function returns an id named numeric field which shows the order of the splitted piece. So while concatenating I use an "order by" clause on the same field this time in descending order
Upvotes: 2
Reputation: 188
This would work to split the string parts -
DECLARE @txt NVARCHAR(500)= 'https://www.site.sharepoint.com/sites/test/AB-19-CALL';
SELECT value
FROM STRING_SPLIT(REVERSE(SUBSTRING(REVERSE(@txt), 1, CHARINDEX('/', REVERSE(@txt))-1)), '-');(substring(reverse(@txt),1,charindex('/',reverse(@txt))-1)),'-')
Upvotes: 2