Using T-SQL, return nth delimited element from a string
Here is my initial solution...
It is based on work by Aaron Bertrand http://www.sqlperformance.com/2012/07/t-sql-queries/split-strings
I simply changed the return type to make it a scalar function.
Example:
SELECT dbo.GetSplitString_CTE('1,222,2,67,888,1111',',',4)
CREATE FUNCTION dbo.GetSplitString_CTE
(
@List VARCHAR(MAX),
@Delimiter VARCHAR(255),
@ElementNumber int
)
RETURNS VARCHAR(4000)
AS
BEGIN
DECLARE @result varchar(4000)
DECLARE @Items TABLE ( position int IDENTITY PRIMARY KEY,
Item VARCHAR(4000)
)
DECLARE @ll INT = LEN(@List) + 1, @ld INT = LEN(@Delimiter);
WITH a AS
(
SELECT
[start] = 1,
[end] = COALESCE(NULLIF(CHARINDEX(@Delimiter,
@List, @ld), 0), @ll),
[value] = SUBSTRING(@List, 1,
COALESCE(NULLIF(CHARINDEX(@Delimiter,
@List, @ld), 0), @ll) - 1)
UNION ALL
SELECT
[start] = CONVERT(INT, [end]) + @ld,
[end] = COALESCE(NULLIF(CHARINDEX(@Delimiter,
@List, [end] + @ld), 0), @ll),
[value] = SUBSTRING(@List, [end] + @ld,
COALESCE(NULLIF(CHARINDEX(@Delimiter,
@List, [end] + @ld), 0), @ll)-[end]-@ld)
FROM a
WHERE [end] < @ll
)
INSERT @Items SELECT [value]
FROM a
WHERE LEN([value]) > 0
OPTION (MAXRECURSION 0);
SELECT @result=Item
FROM @Items
WHERE position=@ElementNumber
RETURN @result;
END
GO
Get nth word in a string delimited by "."
I'd suggest to use Common Table Expressions:
;WITH CTE AS
(
SELECT 1 AS RowNo, LEFT(MyColumn, CHARINDEX('.', MyColumn)-1) AS Word,
RIGHT(MyColumn, LEN(MyColumn) - CHARINDEX('.', MyColumn)) AS Remainder
FROM Dummy
WHERE CHARINDEX('.', MyColumn) >0
UNION ALL
SELECT RowNo +1, LEFT(Remainder, CHARINDEX('.', Remainder)-1) AS Word,
RIGHT(Remainder, LEN(Remainder) - CHARINDEX('.', Remainder)) AS Remainder
FROM CTE
WHERE CHARINDEX('.', Remainder) >0
UNION ALL
SELECT RowNo+ 1, Remainder As Word, NULL As Remainder
FROM CTE
WHERE CHARINDEX('.', Remainder) = 0
)
SELECT Word
FROM CTE
WHERE RowNo = 3
Result:
X24
A12151
SQLFiddle
For further details, please see: Recursive Queries Using Common Table Expressions
[EDIT#2]
Assuming that you want to get every single word into different column, you have to change last SELECT
statement to:
SELECT ID, [1], [2], [3], [4]
FROM (
SELECT RowNo, Word, ROW_NUMBER() OVER(PARTITION BY RowNo ORDER BY RowNo) AS ID
FROM CTE
) AS src
PIVOT (MAX(Word) FOR RowNo IN([1], [2], [3], [4])) AS pvt
Result:
ID 1 2 3 4
1 2345 35S982F A12151 AB4R
2 STR4 Z2Z2 X24 (null)
How to select the nth item in a field with separated values in a SQL database table?
How about this:
SELECT path, value
FROM @table1
OUTER APPLY (
SELECT value
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)), value
FROM string_split(path, '_')
) split (rn, value)
WHERE rn = 3
) splitval;
Extracting nth field of string delimited by ":" stored in a SQL column
Perhaps a little XML as the parser
Example
Select A.Format
,B.*
From YourTable A
Cross Apply (
Select Pos2 = ltrim(rtrim(xDim.value('/x[2]','varchar(max)')))
,Pos3 = ltrim(rtrim(xDim.value('/x[3]','varchar(max)')))
,Pos4 = ltrim(rtrim(xDim.value('/x[4]','varchar(max)')))
From (Select Cast('<x>' + replace((Select replace(A.Format,':','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml) as xDim) as A
) B
Returns
Format Pos2 Pos3 Pos4
GT:AD:DP:GQ:PL AD DP GQ
GT:AD:DP:GQ:PL AD DP GQ
GT:AD:DP:GQ:PL AD DP GQ
GT:AD:DP:GQ:PL AD DP GQ
GT:AD:DP:GQ:PL AD DP GQ
GT:AD:DP:GQ:PGT:PID:PL AD DP GQ
GT:AD:DP:GQ:PL AD DP GQ
GT:AD:DP:GQ:PGT:PID:PL AD DP GQ
GT:AD:DP:GQ:PGT:PID:PL AD DP GQ
GT:AD:DP:GQ:PGT:PID:PL AD DP GQ
GT:AD:DP:GQ:PGT:PID:PL AD DP GQ
Or a Simple version
Select A.Format
,Pos2 = Cast('<x>' + replace(Format,':','</x><x>')+'</x>' as xml).value('/x[2]','varchar(max)')
,Pos3 = Cast('<x>' + replace(Format,':','</x><x>')+'</x>' as xml).value('/x[3]','varchar(max)')
,Pos4 = Cast('<x>' + replace(Format,':','</x><x>')+'</x>' as xml).value('/x[4]','varchar(max)')
From YourTable A
Or if Open to a UDF
Take a peek at TSQL/SQL Server - table function to parse/split delimited string to multiple/separate columns
EDIT - Update for Sample
Select A.Format
,GT = Cast('<x>' + replace(Sample,':','</x><x>')+'</x>' as xml).value('/x[1]','varchar(max)')
,AD = Cast('<x>' + replace(Sample,':','</x><x>')+'</x>' as xml).value('/x[2]','varchar(max)')
,DP = Cast('<x>' + replace(Sample,':','</x><x>')+'</x>' as xml).value('/x[3]','varchar(max)')
,GQ = Cast('<x>' + replace(Sample,':','</x><x>')+'</x>' as xml).value('/x[4]','varchar(max)')
From YourTable A
SQL Server - find nth occurrence in a string
One way (2k8);
select 'abc_1_2_3_4.gif ' as img into #T
insert #T values ('zzz_12_3_3_45.gif')
;with T as (
select 0 as row, charindex('_', img) pos, img from #T
union all
select pos + 1, charindex('_', img, pos + 1), img
from T
where pos > 0
)
select
img, pos
from T
where pos > 0
order by img, pos
>>>>
img pos
abc_1_2_3_4.gif 4
abc_1_2_3_4.gif 6
abc_1_2_3_4.gif 8
abc_1_2_3_4.gif 10
zzz_12_3_3_45.gif 4
zzz_12_3_3_45.gif 7
zzz_12_3_3_45.gif 9
zzz_12_3_3_45.gif 11
Update
;with T(img, starts, pos) as (
select img, 1, charindex('_', img) from #t
union all
select img, pos + 1, charindex('_', img, pos + 1)
from t
where pos > 0
)
select
*, substring(img, starts, case when pos > 0 then pos - starts else len(img) end) token
from T
order by img, starts
>>>
img starts pos token
abc_1_2_3_4.gif 1 4 abc
abc_1_2_3_4.gif 5 6 1
abc_1_2_3_4.gif 7 8 2
abc_1_2_3_4.gif 9 10 3
abc_1_2_3_4.gif 11 0 4.gif
zzz_12_3_3_45.gif 1 4 zzz
zzz_12_3_3_45.gif 5 7 12
zzz_12_3_3_45.gif 8 9 3
zzz_12_3_3_45.gif 10 11 3
zzz_12_3_3_45.gif 12 0 45.gif
SQL split based on delimeter, keep only second element
SELECT RIGHT(ColName , LEN(ColName) - CHARINDEX('\', ColName) )
FROM TABLEName
OR
SELECT PARSENAME(REPLACE(ColName , '\' , '.'),1)
FROM TableName
Related Topics
Postgres Query to Check a String Is a Number
Posgresql - Error: Relation "Table_Name" Does Not Exist. How to Query Without Schema Name
Er_Access_Denied_Error: Access Denied for User ''@'Localhost' (Using Password: No)
How to Search Json Array in MySQL
How to Select Multiple Values in One Field MySQL
Sql: How to Get Both Match and Non-Match Records
How to Convert Bigint (Unix Timestamp) to Datetime in SQL Server
Loop Through Table Rows and Call Stored Procedure on Every Row
Pg_Restore: [Archiver] Unsupported Version (1.14) in File Header
Auto Increment the Column Value by 1 Conditionally in Select Query in SQL
Regex to Filter for Numers With and Without Dots
How to Get Textual Contents from Blob in Oracle SQL
How to Convert from Blob to Text in MySQL
Extract Number from String With Oracle Function
Formatting Numbers by Padding With Leading Zeros in SQL Server