I have a table like this
Value String
-------------------
1 Cleo, Smith
I want to separate the comma delimited string into two colu
question is simple, but problem is hot :)
So I create some wrapper for string_split() which pivot result in more generic way. It's table function which returns values (nn, value1, value2, ... , value50) - enough for most CSV lines. If there are more values, they will wrap to next line - nn indicate line number. Set third parameter @columnCnt = [yourNumber] to wrap at specific position:
alter FUNCTION fn_Split50
(
@str varchar(max),
@delim char(1),
@columnCnt int = 50
)
RETURNS TABLE
AS
RETURN
(
SELECT *
FROM (SELECT
nn = (nn - 1) / @columnCnt + 1,
nnn = 'value' + cast(((nn - 1) % @columnCnt) + 1 as varchar(10)),
value
FROM (SELECT
nn = ROW_NUMBER() over (order by (select null)),
value
FROM string_split(@str, @delim) aa
) aa
where nn > 0
) bb
PIVOT
(
max(value)
FOR nnn IN (
value1, value2, value3, value4, value5, value6, value7, value8, value9, value10,
value11, value12, value13, value14, value15, value16, value17, value18, value19, value20,
value21, value22, value23, value24, value25, value26, value27, value28, value29, value30,
value31, value32, value33, value34, value35, value36, value37, value38, value39, value40,
value41, value42, value43, value44, value45, value46, value47, value48, value49, value50
)
) AS PivotTable
)
Example of using:
select * from dbo.fn_split50('zz1,aa2,ss3,dd4,ff5', ',', DEFAULT)
select * from dbo.fn_split50('zz1,aa2,ss3,dd4,ff5,gg6,hh7,jj8,ww9,qq10', ',', 3)
select * from dbo.fn_split50('zz1,11,aa2,22,ss3,33,dd4,44,ff5,55,gg6,66,hh7,77,jj8,88,ww9,99,qq10,1010', ',',2)
Hope, it will helps :)
Try this (change instances of ' ' to ',' or whatever delimiter you want to use)
CREATE FUNCTION dbo.Wordparser
(
@multiwordstring VARCHAR(255),
@wordnumber NUMERIC
)
returns VARCHAR(255)
AS
BEGIN
DECLARE @remainingstring VARCHAR(255)
SET @remainingstring=@multiwordstring
DECLARE @numberofwords NUMERIC
SET @numberofwords=(LEN(@remainingstring) - LEN(REPLACE(@remainingstring, ' ', '')) + 1)
DECLARE @word VARCHAR(50)
DECLARE @parsedwords TABLE
(
line NUMERIC IDENTITY(1, 1),
word VARCHAR(255)
)
WHILE @numberofwords > 1
BEGIN
SET @word=LEFT(@remainingstring, CHARINDEX(' ', @remainingstring) - 1)
INSERT INTO @parsedwords(word)
SELECT @word
SET @remainingstring= REPLACE(@remainingstring, Concat(@word, ' '), '')
SET @numberofwords=(LEN(@remainingstring) - LEN(REPLACE(@remainingstring, ' ', '')) + 1)
IF @numberofwords = 1
BREAK
ELSE
CONTINUE
END
IF @numberofwords = 1
SELECT @word = @remainingstring
INSERT INTO @parsedwords(word)
SELECT @word
RETURN
(SELECT word
FROM @parsedwords
WHERE line = @wordnumber)
END
Example usage:
SELECT dbo.Wordparser(COLUMN, 1),
dbo.Wordparser(COLUMN, 2),
dbo.Wordparser(COLUMN, 3)
FROM TABLE
This function is most fast:
CREATE FUNCTION dbo.F_ExtractSubString
(
@String VARCHAR(MAX),
@NroSubString INT,
@Separator VARCHAR(5)
)
RETURNS VARCHAR(MAX) AS
BEGIN
DECLARE @St INT = 0, @End INT = 0, @Ret VARCHAR(MAX)
SET @String = @String + @Separator
WHILE CHARINDEX(@Separator, @String, @End + 1) > 0 AND @NroSubString > 0
BEGIN
SET @St = @End + 1
SET @End = CHARINDEX(@Separator, @String, @End + 1)
SET @NroSubString = @NroSubString - 1
END
IF @NroSubString > 0
SET @Ret = ''
ELSE
SET @Ret = SUBSTRING(@String, @St, @End - @St)
RETURN @Ret
END
GO
Example usage:
SELECT dbo.F_ExtractSubString(COLUMN, 1, ', '),
dbo.F_ExtractSubString(COLUMN, 2, ', '),
dbo.F_ExtractSubString(COLUMN, 3, ', ')
FROM TABLE
it is so easy, you can take it by below query:
DECLARE @str NVARCHAR(MAX)='ControlID_05436b78-04ba-9667-fa01-9ff8c1b7c235,3'
SELECT LEFT(@str, CHARINDEX(',',@str)-1),RIGHT(@str,LEN(@str)-(CHARINDEX(',',@str)))
Your purpose can be solved using following query -
Select Value , Substring(FullName, 1,Charindex(',', FullName)-1) as Name,
Substring(FullName, Charindex(',', FullName)+1, LEN(FullName)) as Surname
from Table1
There is no readymade Split function in sql server, so we need to create user defined function.
CREATE FUNCTION Split (
@InputString VARCHAR(8000),
@Delimiter VARCHAR(50)
)
RETURNS @Items TABLE (
Item VARCHAR(8000)
)
AS
BEGIN
IF @Delimiter = ' '
BEGIN
SET @Delimiter = ','
SET @InputString = REPLACE(@InputString, ' ', @Delimiter)
END
IF (@Delimiter IS NULL OR @Delimiter = '')
SET @Delimiter = ','
--INSERT INTO @Items VALUES (@Delimiter) -- Diagnostic
--INSERT INTO @Items VALUES (@InputString) -- Diagnostic
DECLARE @Item VARCHAR(8000)
DECLARE @ItemList VARCHAR(8000)
DECLARE @DelimIndex INT
SET @ItemList = @InputString
SET @DelimIndex = CHARINDEX(@Delimiter, @ItemList, 0)
WHILE (@DelimIndex != 0)
BEGIN
SET @Item = SUBSTRING(@ItemList, 0, @DelimIndex)
INSERT INTO @Items VALUES (@Item)
-- Set @ItemList = @ItemList minus one less item
SET @ItemList = SUBSTRING(@ItemList, @DelimIndex+1, LEN(@ItemList)-@DelimIndex)
SET @DelimIndex = CHARINDEX(@Delimiter, @ItemList, 0)
END -- End WHILE
IF @Item IS NOT NULL -- At least one delimiter was encountered in @InputString
BEGIN
SET @Item = @ItemList
INSERT INTO @Items VALUES (@Item)
END
-- No delimiters were encountered in @InputString, so just return @InputString
ELSE INSERT INTO @Items VALUES (@InputString)
RETURN
END -- End Function
GO
---- Set Permissions
--GRANT SELECT ON Split TO UserRole1
--GRANT SELECT ON Split TO UserRole2
--GO
With SQL Server 2016 we can use string_split to accomplish this:
create table commasep (
id int identity(1,1)
,string nvarchar(100) )
insert into commasep (string) values ('John, Adam'), ('test1,test2,test3')
select id, [value] as String from commasep
cross apply string_split(string,',')