i want to remove string after colon in sql server - sql

-- i need data like this F11.20,F13.20,F14.10 in sql server
declare #S varchar(200) = ',F11.20:,F13.20:Sedative, hypnotic o,F14.10:Cocaine abuse, uncom';
select left(#S, charindex(':', #S, charindex(':', #S)+2)-2);

Any Split/Parse Function would do the trick, but you would have to perform secondary logic to clean the parsed string. That said, I modified a parse function to accept any two non-like delimiters (start/end). In this case a , and :
Also, being a Table-Valued-Function, it is easy to incorporate into a CROSS APPLY or as a stand-alone as illustrated below.
Example
Select NewString = Stuff((Select ',' +RetVal
From [dbo].[udf-Str-Extract](#S,',',':')
For XML Path ('')),1,1,'')
Returns
F11.20,F13.20,F14.10
The UDF if Interested
CREATE FUNCTION [dbo].[udf-Str-Extract] (#String varchar(max),#Delimiter1 varchar(100),#Delimiter2 varchar(100))
Returns Table
As
Return (
with cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
cte2(N) As (Select Top (IsNull(DataLength(#String),0)) Row_Number() over (Order By (Select NULL)) From (Select N=1 From cte1 N1,cte1 N2,cte1 N3,cte1 N4,cte1 N5,cte1 N6) A ),
cte3(N) As (Select 1 Union All Select t.N+DataLength(#Delimiter1) From cte2 t Where Substring(#String,t.N,DataLength(#Delimiter1)) = #Delimiter1),
cte4(N,L) As (Select S.N,IsNull(NullIf(CharIndex(#Delimiter1,#String,s.N),0)-S.N,8000) From cte3 S)
Select RetSeq = Row_Number() over (Order By N)
,RetPos = N
,RetVal = left(RetVal,charindex(#Delimiter2,RetVal)-1)
From (Select *,RetVal = Substring(#String, N, L) From cte4) A
Where charindex(#Delimiter2,RetVal)>1
/*
Max Length of String 1MM characters
Declare #String varchar(max) = 'Dear [[FirstName]] [[LastName]], ...'
Select * From [dbo].[udf-Str-Extract] (#String,'[[',']]')
*/
EDIT Just to Help with the Visualization
If you executed the TVF alone:
declare #S varchar(200) = ',F11.20:,F13.20:Sedative, hypnotic o,F14.10:Cocaine abuse, uncom';
Select * From [dbo].[udf-Str-Extract](#S,',',':')
Returns
RetSeq RetPos RetVal
1 2 F11.20
2 10 F13.20
3 38 F14.10
EDIT 2 - Execute via Cross Apply
Declare #YourTable table (ID int,SomeString varchar(200))
Insert Into #YourTable values
(1,',F11.20:,F13.20:Sedative, hypnotic o,F14.10:Cocaine abuse, uncom'),
(2,',Z99.55:,Z25.10:Someother text')
Select A.ID
,B.*
From #YourTable A
Cross Apply (
Select NewString = Stuff((Select ',' +RetVal
From [dbo].[udf-Str-Extract](A.SomeString,',',':')
For XML Path ('')),1,1,'')
) B
Returns
ID NewString
1 F11.20,F13.20,F14.10
2 Z99.55,Z25.10

If the text you're extracting is always in the form of (letter, number, number, ., number, number) and there's always 3 instances of that text, then you could do this:
WITH
s1(string, ci) AS (SELECT #S, CHARINDEX(':', #S)),
s2(ci) AS (SELECT CHARINDEX(':', #S, ci+1) FROM s1),
s3(ci) AS (SELECT CHARINDEX(':', #S, ci+1) FROM s2)
SELECT
SUBSTRING(string, s1.ci-6, 6)+','+
SUBSTRING(string, s2.ci-6, 6)+','+
SUBSTRING(string, s3.ci-6, 6)
FROM s1, s2, s3;
Execution Plan:
It doesn't get any more efficient then that.
If its always the 6 characters before any instance of ":" you can grab a copy of NGrams8K and do this:
declare #S varchar(200) = ',F11.20:,F13.20:Sedative, hypnotic o,F14.10:Cocaine abuse, uncom';
SELECT NewString = STUFF
((SELECT ','+SUBSTRING(#S, position-6, 6)
FROM dbo.NGrams8k(#S, 1)
WHERE token = ':'
FOR XML PATH('')),1,1,'');
Another way using NGrams8K and a variable:
declare #S varchar(200) = ',F11.20:,F13.20:Sedative, hypnotic o,F14.10:Cocaine abuse, uncom';
declare #newstring varchar(100)='';
declare #S varchar(200) = ',F11.20:,F13.20:Sedative, hypnotic o,F14.10:Cocaine abuse, uncom';
declare #newstring varchar(100)='';
SELECT
#newstring +=
CASE #newstring WHEN '' THEN '' ELSE ',' END +SUBSTRING(#S, position-6, 6)
FROM dbo.NGrams8k(#S, 1)
WHERE token = ':';
SELECT #newstring;

Related

Remove style from database (SQL Server)

I am working on old database table where there are values that have CSS attached to it.
For example:
<font size="25">Select your gender?</font>
<font size="25">Select your country?</font>
Is there any way to remove all the styling at once besides removing it one at a time?
I want to remove <font size="25"></font> and just keep Select your gender
Thank you in advance!
With the aid of a Helper Function
Example
Declare #YourTable table (SomeCol varchar(max) )
Insert Into #YourTable values
('1.<font size="25">Select your <b>gender</b>?</font>') -- Notice nested tags <b> ..</b>
,('2.<font size="25">Select your <span style="color:blue;">country</span>?</font>')
Select B.*
From #YourTable A
Cross Apply (
Select NewStr = Stuff((Select '' +RetVal
From [dbo].[tvf-Str-Extract](SomeCol,'>','<')
Order By RetSeq
For XML Path ('')),1,0,'')
) B
Returns
NewStr
1.Select your gender?
2.Select your country?
The function if interested
CREATE FUNCTION [dbo].[tvf-Str-Extract] (#String varchar(max),#Delim1 varchar(100),#Delim2 varchar(100))
Returns Table
As
Return (
Select RetSeq = row_number() over (order by RetSeq)
,RetVal = left(RetVal,charindex(#Delim2,RetVal)-1)
From (
Select RetSeq = row_number() over (order by 1/0)
,RetVal = ltrim(rtrim(B.i.value('(./text())[1]', 'varchar(max)')))
From ( values (convert(xml,'<x>' + replace((Select replace(#String,#Delim1,'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>').query('.'))) as A(XMLData)
Cross Apply XMLData.nodes('x') AS B(i)
) C1
Where charindex(#Delim2,RetVal)>1
)
/*
Declare #String varchar(max) = 'Dear [[FirstName]] [[LastName]], ...'
Select * From [dbo].[tvf-Str-Extract] (#String,'[[',']]')
*/
A combination of charindex, substring and left can help
The problem is you have be sure that the data you need for every row is in the form:
xxxxx>DATA<*****, that you don,t a row in a form like xxxxx>DATA1<*****xxxxx>DATA2<*****
variable example:
declare #string as varchar(1000)
declare #NoLeft as varchar(1000)
declare #NoRight as varchar(1000)
set #string = '1.<font size="25">Select your gender?</font>';
select #string
SELECT #NoLeft = substring(#string, CHARINDEX( '>', #string) + 1 , len(#string)-CHARINDEX( '>', #string))
select #NoLeft
SELECT #NoRight = left(#NoLeft, CHARINDEX( '<', #NoLeft) - 1)
select #NoRight
For a table it becomes
select left(substring(ColumnName, CHARINDEX( '>', ColumnName) + 1 , len(ColumnName)-CHARINDEX( '>', ColumnName)), CHARINDEX( '<', substring(ColumnName, CHARINDEX( '>', ColumnName) + 1 , len(ColumnName)-CHARINDEX( '>', ColumnName))) - 1)
From TableName

How to get first character beside underscore for a given string

input:
string
'abc_def_ghk_lmn'
output:
dgl
You can try this (or even create a function):
DECLARE #str varchar(250) = 'abc_def_ghk_lmn'
DECLARE #result varchar(250)='';
WHILE(charindex('_',#str)!=0)
BEGIN
DECLARE #position int = charindex('_',#str)
SET #result += substring(#str,#position+1,1)
SET #str = substring(#str,#position+1,len(#str))
END
SELECT #result
You can use a recursive CTE:
IF OBJECT_ID('tempdb..#t') is not null drop table #t
SELECT * into #t from (values (N'abc_def_ghk_lmn'), (N'a_f_k_n'), (null), ('____'), ('asasas'), ('a_sasas'), ('asas_')) T(val);
;WITH CTE AS
(
SELECT
Cast(SUBSTRING(T.val, CHARINDEX('_',T.val,1) + 1, 1) as nvarchar(4000)) FC
,CHARINDEX('_', T.val, 1) CI
,val
,0 [level]
from #t T
where CHARINDEX('_', T.val, 1) > 0
union all
SELECT
Cast(T.FC + SUBSTRING(T.val, CHARINDEX('_',T.val,T.CI+1) + 1, 1) as nvarchar(4000)) FC
,CHARINDEX('_', T.val, T.CI+1) CI
,val
,t.[level] + 1
from CTE T
where CHARINDEX('_',T.val,T.CI+1) > 0
)
, Res AS
(
SELECT
*
,ROW_NUMBER() OVER (Partition by val order by [level] desc) RN
from CTE
)
SELECT * from Res where RN = 1
This uses Jeff Moden's DelimitedSplit8K Function. Firstly because i don't know what version of SQL Server you are using, and secondly, the inbuilt function STRING_SPLIT (available in SQL Server 2016 onwards) doesn't include an Item Number value (thus how does one exclude the first result?):
SELECT (SELECT LEFT(Item, 1)
FROM DelimitedSplit8K ('abc_def_ghk_lmn','_') DS
WHERE DS.ItemNumber > 1
FOR XML PATH(''));
Edit:
Example with a dataset:
WITH VTE AS(
SELECT *
FROM (VALUES ('asdgsad_sdfh_sadfh'),('_ashdf+ashd'),('jsda_sdkhfsdjf_654_asdfkhasd_567465413_kasbgdjkasdj')) V(S))
SELECT (SELECT LEFT(Item, 1)
FROM DelimitedSplit8K (S,'_') DS
WHERE DS.ItemNumber > 1
FOR XML PATH('')) AS FirstCharacters
FROM VTE;
Try this:
DECLARE #String VARCHAR(50)= 'abc_def_ghk_lmn',#Result VARCHAR(10)=''
WHILE CHARINDEX('_',#String)>0
BEGIN
SELECT #Result=#Result + SUBSTRING(#String,CHARINDEX('_',#String)+1,1)
SELECT #String=RIGHT(#String,LEN(#String)- CHARINDEX('_',#String))
END
SELECT #Result FinalResult
OUTPUT:
FinalResult
dgl
Please try this -...Always use SET BASED Approach
SOLUTION
DECLARE #x AS XML=''
DECLARE # AS VARCHAR(1000) = 'abc_def_ghk_lmn_'
SET #x = CAST('<A>'+ REPLACE(#,'_','</A><A>')+ '</A>' AS XML)
;WITH CTE AS
(
SELECT t.value('.', 'VARCHAR(10)') Value FROM #x.nodes('/A') AS x(t)
)
,CTE1 AS
(
SELECT * , ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) rnk FROM CTE
)
,CTE2 AS
(
SELECT SUBSTRING(Value,1,1) v , rnk FROM CTE1
)
SELECT CASE WHEN LEFT(#,1) <> '_' THEN MAX(SUBSTRING(u,2,LEN(u))) ELSE MAX(u) END finalstr from (
SELECT
(
SELECT '' + v
FROM CTE2 a
FOR XML PATH('')
)u
FROM CTE2 )x
OUTPUT
finalstr
---------------
dgl
(1 row affected)
Try this below
DECLARE #str TAble(String varchar(250))
INSERT INTO #str
SELECT 'abc_def_ghk_lmn_opq_rst_uvw_xyz'
SELECT STUFF((SELECT ''+LEFT(String,1) FROM
(
SELECT Split.a.value('.','Varchar(1000)') As String,
ROW_NUMBER()OVER(ORDER BY (SELECT 1)) AS Id FROM
(
SELECT CASt('<S>'+REPLACE(String,'_','</S><S>')+'</S>' AS XML )AS String
FROM #str
)as A
CROSS APPLY String.nodes ('S') AS Split(a)
)dt
WHERE dt.Id <>1
FOR XML PATH ('')),1,0,'') AS ExpectedColumn
Result
ExpectedColumn
--------------
dglorux
Use LEFT to get the left part and INSTR to find underscore and finally get your string:
SELECT LEFT(FIELD_1, CHARINDEX('_', FIELD_1) - 2) AS [ANY_ALIAS]
FROM TABLE_1;
EDIT: Now is MSSQL... ;D

split semicolon delimiter SQL to rows [duplicate]

This question already has answers here:
T-SQL split string
(27 answers)
Closed 6 years ago.
Just want to ask for help.
I'm trying to split delimited values with a semicolon as a delimiter.
Comma cannot be replaced to the semicolon since there are values that have comma.
ID Value
1 | A&B;C;D;E, F
Transform to:
ID Value
1 A&B
1 C
1 D
1 E, F
I tried tweaking the SQL scripts that i got online but to no success
SELECT F1.ID,
O.splitdata
FROM
(
SELECT OldID,
cast('<X>'+replace((SELECT ColumnName + '' FOR XML PATH('')),';','</X><X>')+'</X>' as XML) as xmlfilter from TableName F
)F1
CROSS APPLY
(
SELECT fdata.D.value('.','varchar(max)') as splitdata
FROM f1.xmlfilter.nodes('X') as fdata(D)) O
It works for some of my columns but if the columns have special or Illegal characters it outputs this error:
Msg 9411, Level 16, State 1, Line 2
XML parsing: line 1, character 16, semicolon expected
Thanks!
If you do not like a function, or if you do not have the rights to create a new function, you can use the quite fast XML approach. In your case it needs some extra effort to get this XML-safe (due to special characters and the ; as delimiter):
Declare #Dummy table (ID int, SomeTextToSplit varchar(max))
Insert Into #Dummy values
(1,'A&B;C;D;E, F')
,(2,'"C" & "D";<C>;D;E, F');
DECLARE #Delimiter VARCHAR(10)=';';
WITH Casted AS
(
SELECT *
,CAST('<x>' + REPLACE((SELECT REPLACE(SomeTextToSplit,#Delimiter,'§§Split$me$here§§') AS [*] FOR XML PATH('')),'§§Split$me$here§§','</x><x>') + '</x>' AS XML) AS SplitMe
FROM #Dummy
)
SELECT Casted.*
,x.value('.','nvarchar(max)') AS Part
FROM Casted
CROSS APPLY SplitMe.nodes('/x') AS A(x)
The result
1 A&B
1 C
1 D
1 E, F
2 "C" & "D"
2 <C>
2 D
2 E, F
Option 1 with a UDF
Declare #YourTable table (ID int, Value varchar(max))
Insert Into #YourTable values
(1,'A&B;C;D;E, F')
Select A.ID
,B.*
From #YourTable A
Cross Apply [dbo].[udf-Str-Parse-8K](A.Value,';') B
Option 2 without a UDF
Select A.ID
,B.*
From #YourTable A
Cross Apply (
Select RetSeq = Row_Number() over (Order By (Select null))
,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>' + replace((Select replace(A.Value,';','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
) B
Both Return
ID RetSeq RetVal
1 1 A&B
1 2 C
1 3 D
1 4 E, F
This UDF is XML Safe and VERY fast
CREATE FUNCTION [dbo].[udf-Str-Parse-8K] (#String varchar(max),#Delimiter varchar(25))
Returns Table
As
Return (
with cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
cte2(N) As (Select Top (IsNull(DataLength(#String),0)) Row_Number() over (Order By (Select NULL)) From (Select N=1 From cte1 a,cte1 b,cte1 c,cte1 d) A ),
cte3(N) As (Select 1 Union All Select t.N+DataLength(#Delimiter) From cte2 t Where Substring(#String,t.N,DataLength(#Delimiter)) = #Delimiter),
cte4(N,L) As (Select S.N,IsNull(NullIf(CharIndex(#Delimiter,#String,s.N),0)-S.N,8000) From cte3 S)
Select RetSeq = Row_Number() over (Order By A.N)
,RetVal = LTrim(RTrim(Substring(#String, A.N, A.L)))
From cte4 A
);
--Orginal Source http://www.sqlservercentral.com/articles/Tally+Table/72993/
--Much faster than str-Parse, but limited to 8K
--Select * from [dbo].[udf-Str-Parse-8K]('Dog,Cat,House,Car',',')
--Select * from [dbo].[udf-Str-Parse-8K]('John||Cappelletti||was||here','||')
Please use the function below to split a string by a specific delimiter:
CREATE FUNCTION [dbo].[Split](#String varchar(8000), #Delimiter char(1))
returns #temptable TABLE (SplitValue varchar(8000))
as
begin
declare #idx int
declare #slice varchar(8000)
select #idx = 1
if len(#String)<1 or #String is null return
while #idx!= 0
begin
set #idx = charindex(#Delimiter,#String)
if #idx!=0
set #slice = left(#String,#idx - 1)
else
set #slice = #String
if(len(#slice)>0)
insert into #temptable(SplitValue) values(#slice)
set #String = right(#String,len(#String) - #idx)
if len(#String) = 0 break
end
return
end
Let me know if you have any queries.
Thanks .

How to sort numeric values in string in SQL Server

Input string -
'0|33|6|2|30|12|4|1|8|29|9|34|7|13|11|5|3|31|10|36|37|37|37|38|39|40|44|65|66'
Output string -
'0|1|2|3|4|5|6|7|8|9|10|11|12|13|29|30|31|33|34|36|37|37|37|38|39|40|44|65|66'
Need this in SQL Server 2008.
I have splitted the value on | and then inserted the values into temp table and then concatenated value. Is there any better approarch?
Without a Parse/Split function
Declare #String varchar(max) = '0|33|6|2|30|12|4|1|8|29|9|34|7|13|11|5|3|31|10|36|37|37|37|38|39|40|44|65|66'
Select Sorted = Stuff((Select '|' +RetVal
From (
Select RetSeq = Row_Number() over (Order By (Select null))
,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>'+ replace((Select #String as [*] For XML Path('')),'|','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
) A
Order By cast(RetVal as int)
For XML Path ('')),1,1,'')
With a Parse/Split function'
Declare #String varchar(max) = '0|33|6|2|30|12|4|1|8|29|9|34|7|13|11|5|3|31|10|36|37|37|37|38|39|40|44|65|66'
Select Sorted = Stuff((Select '|' +RetVal
From [dbo].[udf-Str-Parse-8K](#String,'|')
Order By cast(RetVal as int)
For XML Path ('')),1,1,'')
Both Return
0|1|2|3|4|5|6|7|8|9|10|11|12|13|29|30|31|33|34|36|37|37|37|38|39|40|44|65|66
The UDF if needed
CREATE FUNCTION [dbo].[udf-Str-Parse-8K] (#String varchar(max),#Delimiter varchar(25))
Returns Table
As
Return (
with cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
cte2(N) As (Select Top (IsNull(DataLength(#String),0)) Row_Number() over (Order By (Select NULL)) From (Select N=1 From cte1 a,cte1 b,cte1 c,cte1 d) A ),
cte3(N) As (Select 1 Union All Select t.N+DataLength(#Delimiter) From cte2 t Where Substring(#String,t.N,DataLength(#Delimiter)) = #Delimiter),
cte4(N,L) As (Select S.N,IsNull(NullIf(CharIndex(#Delimiter,#String,s.N),0)-S.N,8000) From cte3 S)
Select RetSeq = Row_Number() over (Order By A.N)
,RetVal = LTrim(RTrim(Substring(#String, A.N, A.L)))
From cte4 A
);
--Orginal Source http://www.sqlservercentral.com/articles/Tally+Table/72993/
--Much faster than str-Parse, but limited to 8K
--Select * from [dbo].[udf-Str-Parse-8K]('Dog,Cat,House,Car',',')
--Select * from [dbo].[udf-Str-Parse-8K]('John||Cappelletti||was||here','||')
declare #str varchar(100) =
'0|33|6|2|30|12|4|1|8|29|9|34|7|13|11|5|3|31|10|36|37|37|37|38|39|40|44|65|66';
declare #s varchar(100) = '|' + #str + '|';
declare #result varchar(100);
with D(d) as
(
select v from (values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) V(v)
),
N(n) as
(
select top (len(#s) - 1)
row_number() over (order by (select 1)) from D d1, D d2
),
S(s) as
(
select substring(#s, n + 1, charindex('|', #s, n + 1) - (n + 1))
from N where substring(#s, n, 1) = '|'
)
select top (100) #result = isnull(#result + '|', '') + s
from S order by cast(s as int);
print #result;

SQL select string between known identical characters

I have code which selects the string between the first and second '/' in a typical string which may look like this:
2014-Ceilings/Ceilings/Repair/Asbestos/Supalux
The following code correctly returns the value 'Ceilings' in the above example.
SELECT
REPLACE (LEFT(SUBSTRING(ElementPath,CHARINDEX
('/',ElementPath)+1,LEN(ElementPath)),CHARINDEX
('/',SUBSTRING(ElementPath, CHARINDEX
('/',ElementPath)+1,LEN(ElementPath)))),'/','')
FROM K2_Master.dbo.tbElement
How can I amend it to select the string between the second and third '/' to return the value 'Repair'?
Check this little trick may work :
DECLARE #String VARCHAR(100)= '2014-Ceilings/Ceilings/Repair/Asbestos/Supalux'
SET #String = '<N>' + Replace(#String, '/', '</N><N>')
+ '</N>'
SELECT c.value('/N[1]', 'varchar(30)'),
c.value('/N[2]', 'varchar(30)'),
c.value('/N[3]', 'varchar(30)')
FROM (SELECT Cast(#String AS XML)) t(c)
SELECT c1.value('.', 'varchar(30)')
FROM (SELECT CAST(#String AS XML)) t(c)
CROSS APPLY c.nodes('/N') AS t1(c1)
SELECT value
FROM (SELECT c1.value('.', 'varchar(30)') AS value,
ROW_NUMBER()
OVER(
ORDER BY (SELECT 1)) rn
FROM (SELECT Cast(#String AS XML)) t(c)
CROSS APPLY c.nodes('/N') AS t1(c1)) temp
WHERE rn = 3
In your case
SELECT c.value('/N[1]', 'varchar(30)'),
c.value('/N[2]', 'varchar(30)'),
c.value('/N[3]', 'varchar(30)')
FROM (SELECT Cast ('<N>' + Replace( Replace (ElementPath, '/', '</N><N>'),'&','&')
+ '</N>' AS XML)
FROM K2_Master.dbo.tbElement) t(c)
I chased your question, and reached a lengthy result..
DECLARE #a VARCHAR(40) = '2014-Ceilings/Ceilings/Repair/Asbestos/Supalux'
SELECT #a
,LEFT(
SUBSTRING(SUBSTRING(#a,CHARINDEX('/',#a,1)+1,LEN(#a)),CHARINDEX('/',SUBSTRING(#a,CHARINDEX('/',#a,1)+1,LEN(#a)),1)+1,LEN(SUBSTRING(#a,CHARINDEX('/',#a,1)+1,LEN(#a)))),
CHARINDEX('/',SUBSTRING(SUBSTRING(#a,CHARINDEX('/',#a,1)+1,LEN(#a)),CHARINDEX('/',SUBSTRING(#a,CHARINDEX('/',#a,1)+1,LEN(#a)),1)+1,LEN(SUBSTRING(#a,CHARINDEX('/',#a,1)+1,LEN(#a)))),1) - 1
)
Result:
Answer to you comment.
DECLARE #String VARCHAR(100)= '2014-Ceilings/Ceilings/Repair/Asbestos/Supalux',
#value INT = 2
DECLARE #itra INT = 1
WHILE #itra <= #value
BEGIN
SET #String = (SELECT SUBSTRING(#String,CHARINDEX('/',#String,1)+1,LEN(#String)))
--SELECT #String
SET #itra = #itra + 1
END
SELECT LEFT(#String, CHARINDEX('/',#String,1) - 1)
Give the position of '/' as #value and see the result. For the above sql, the result is Repair. If you give #value = 3, result is Asbestos