SQL Server import row string to table columns - sql

I have a table containing the following text per row
"[0,0,0,1,2,4,1,0,0,2,0,0,0,0,847,18207,0,0,0,0,0,0,0,0,0,0,0,0]"
Now i want to insert these 28 values in a table containing 28 columns. I tried a few split functions but these would return only rows.
Any ideas?

using dbo.fnParseString()
INSERT INTO a_table (col1, col2, col3, . . . )
SELECT dbo.fnParseString(-1, ',', str)
,dbo.fnParseString(-2, ',', str)
,dbo.fnParseString(-3, ',', str)
,....
FROM yourtable

DECLARE #x XML
;with cte as (
SELECT '[0,0,0,1,2,4,1,0,0,2,0,0,0,0,847,18207,0,0,0,0,0,0,0,0,0,0,0,0]' as col
)
SELECT #x= (
SELECT CAST('<s>' + REPLACE(REPLACE(REPLACE(col,'[','<a>'),']','</a>'),',','</a><a>') +'</s>'AS XML)
FROM cte
FOR XML PATH('')
)
SELECT t.v.value('a[1]','int'),
t.v.value('a[2]','int'),
t.v.value('a[3]','int'),
...
t.v.value('a[28]','int')
FROM #x.nodes('/s') as t(v)

Related

SQl Server split delimited string into rows

I have a table in SQL Server 2008 database, the table has two columns,as follow:
I want to select the data as following:
This type of operation is rather painful in SQL Server, because the built-in string functions are pretty bad. The referenced question uses a while loop -- which is unnecessary. You can construct this all in one query using a recursive CTE:
with t as (
select 'ali' as col1, 'A;B;C' as col2
),
cte as (
select col1,
convert(varchar(max), left(col2, charindex(';', col2) - 1)) as val,
convert(varchar(max), stuff(col2, 1, charindex(';', col2), '') + ';') as rest
from t
union all
select col1,
convert(varchar(max), left(rest, charindex(';', rest) - 1)) as val,
convert(varchar(max), stuff(rest, 1, charindex(';', rest), '')) as rest
from cte
where rest <> ''
)
select cte.*
from cte;
I had a similar situation and I solved it using XML querying with this as my guide. I am not super proficient with XML queries, so I am hesitant to share my answer because I cannot fully explain it line by line even though it does work. What I do understand is that you replace your separator character (or string) with closing and opening XML tags with a open tag at the very beginning and a close tag at the very end which transforms this...
A;B;C
into this...
<X>A</X>
<X>B</X>
<X>C</X>
You can use XML query syntax to retrieve each of those nodes. There is nothing magical about "X" other than you have to use the same tag in the nodes() method in CROSS APPLY section.
CREATE TABLE Table1
(
Column1 VARCHAR(20)
, Column2 VARCHAR(50)
);
INSERT INTO Table1 (Column1, Column2) VALUES ('Ali', 'A;B;C');
INSERT INTO Table1 (Column1, Column2) VALUES ('Ahmed', 'D;E');
DECLARE #Separator VARCHAR(10);
SET #Separator = ';';
SELECT a.Column1
, b.SplitData
FROM (
SELECT Column1
, CAST('<X>' + REPLACE((
SELECT Column2 AS [*] FOR XML PATH('')
)
, #Separator
, '</X><X>'
) + '</X>' AS XML) xmlfilter
FROM Table1
) AS a
CROSS APPLY (
SELECT LetterIDs.Column2.value('.', 'varchar(50)') AS SplitData
FROM a.xmlfilter.nodes('X') AS LetterIDs(Column2)
) AS b;
Here is the db fiddle. I hope this helps.

Get a specific string

It's my data and every ThroughRouteSid record has the same pattern.
six number and five comma. then I just want to get three and five
number into two record to template Table and get the same Count()
value to these two record.
For example: First record in the picture.
ThroughRouteSid(3730,2428,2428,3935,3935,3938,) Count(32).
I want a result like this:
2428 32 3935 32
I get What number I want.become two record and both have same Count value into template table
you can use XML to get your result, please refer below sample code -
create table #t1( ThroughRouteSid varchar(500) , Cnt int)
insert into #t1
select '3730,2428,2428,3935,3935,3938,' , len('3730,2428,2428,3935,3935,3938,')
union all select '1111,2222,3333,4444,5555,6666,' , len('1111,2222,3333,4444,5555,6666,')
select cast( '<xml><td>' + REPLACE( SUBSTRING(ThroughRouteSid ,1 , len(ThroughRouteSid)-1),',','</td><td>') + '</td></xml>' as xml) XmlData , Cnt
into #t2 from #t1
select XmlData.value('(xml/td)[3]' ,'int' ), Cnt ,XmlData.value('(xml/td)[5]' ,'int' ), Cnt
from #t2
First create the function referring How to Split a string by delimited char in SQL Server. Then try Querying the following
select (SELECT CONVERT(varchar,splitdata) + ' '+ Convert(varchar, [Count])+' ' FROM (select splitdata, ROW_NUMBER() over (ORDER BY (SELECT 100)) row_no
from [dbo].[fnSplitString](ThroughRouteSid,',')
where splitdata != '') as temp where row_no in (2,5)
for xml path('')) as col1 from [yourtable]
If you are using SQL Server 2016 you can do something like this:
create table #temp (ThroughRouteSid varchar(1024),[Count] int)
insert into #temp values
('3730,2428,2428,3935,3935,3938,',32),
('730,428,428,335,935,938,',28)
select
spt.value,
t.[Count]
from #temp t
cross apply (
select value from STRING_SPLIT(t.ThroughRouteSid,',') where LEN(value) > 0
)spt

how to write SQL query for this result?

I have so many long database so I used seq_no in commas separate using more than one sequence store in single column but now I want all sequence in a single column so I am confused how to create this sql result for this.
For example:
TABLE STRUCTURE
SR_NO IS INT ,
SEQ_NO IS VARCHAR(MAX)
SR_NO SEQ_NO
---------------------------------
1 1839073,
2 1850097,1850098,
3 1850099,1850100,1850110
I need to get this result:
SEQ_NO
--------------
1839073
1850097
1850098
1850099
1850100
1850110
Thanks!
declare #t table(Id int,seq varchar(100))
insert into #t (Id,seq) values (1,'1839073,'),(2,'1839073,1850098,'),(3,'1850099,1850100,1850110 ')
;With Cte as (
SELECT A.Id,
Split.a.value('.', 'VARCHAR(100)') AS Seq
FROM
(
SELECT Id,
CAST ('<M>' + REPLACE(seq, ',', '</M><M>') + '</M>' AS XML) AS Data
FROM #t
) AS A CROSS APPLY Data.nodes ('/M') AS Split(a) )
Select ID,Seq from Cte Where Seq > ''
Try splitting it with XML
SELECT SR_NO, t.c.value('.', 'VARCHAR(2000)') COL1
FROM (
SELECT SR_NO, x = CAST('<t>' +
REPLACE(SEQ_NO, ',', '</t><t>') + '</t>' AS XML)
FROM
(values(1,'1839073'),(2, '1850097,1850098'),
(3, '1850099,1850100,1850110')) y(SR_NO, SEQ_NO)
) a
CROSS APPLY x.nodes('/t') t(c)
Result:
SR_NO COL1
1 1839073
2 1850097
2 1850098
3 1850099
3 1850100
3 1850110
You can replace this with your table:
(values (1,'1839073'),(2, '1850097,1850098'),
(3, '1850099,1850100,1850110')) y(SR_NO, SEQ_NO)
This should do it: (Replace YourTableName with your table name)
;WITH CTE(NEW_SEQ_NO, SEQ_NO) as (
SELECT LEFT(SEQ_NO, CHARINDEX(',',SEQ_NO + ',') -1),
STUFF(SEQ_NO, 1, CHARINDEX(',',SEQ_NO + ','), '')
FROM YourTableName
WHERE SEQ_NO <> '' AND SEQ_NO IS NOT NULL
UNION all
SELECT LEFT(SEQ_NO, CHARINDEX(',',SEQ_NO + ',') -1),
STUFF(SEQ_NO, 1, CHARINDEX(',',SEQ_NO + ','), '')
FROM CTE
WHERE SEQ_NO <> '' AND SEQ_NO IS NOT NULL
)
SELECT NEW_SEQ_NO from CTE ORDER BY NEW_SEQ_NO
You can check this topic for more information:
Turning a Comma Separated string into individual rows
I have written the following query after referring Turning a Comma Separated string into individual rows
It will work for you
create table STRUCTURE(SR_NO int, SEQ_NO varchar(max))
insert STRUCTURE select 1, '1839073,'
insert STRUCTURE select 2, '1850097,1850098,'
insert STRUCTURE select 3, '1850099,1850100,1850110'
;with tmp(SR_NO, DataItem, SEQ_NO) as (
select SR_NO, LEFT(SEQ_NO, CHARINDEX(',',SEQ_NO+',')-1),
STUFF(SEQ_NO, 1, CHARINDEX(',',SEQ_NO+','), '')
from STRUCTURE
union all
select SR_NO, LEFT(SEQ_NO, CHARINDEX(',',SEQ_NO+',')-1),
STUFF(SEQ_NO, 1, CHARINDEX(',',SEQ_NO+','), '')
from tmp
where SEQ_NO > ''
)
Select DataItem as SEQ_NO from tmp order by SEQ_NO;

Inserting multiple value in table with String input

I am passing one string to store procedure : 1:20,2:30,4:50
It contains id and appropriate value for it.
how can I add value as shown in below table in database.
ID Value
1 20
2 30
4 50
I have already "stringSplit" function which works perfectly and gives out put in row value some think like this :
1:20
2:30
4:50
can anyone please help me to insert data into table with any solution.
i already try this solution
insert <table> (colname)
select y.item
from dbo.SplitString(#testString, ':') x
cross apply
dbo.SplitString(x.item, ',') y
but this will return duplicate value as more as id value.
my store procedure is
CREATE PROCEDURE [dbo].[temp_result_insert]
#dataString varchar(max)
AS
insert into tempTable(id,marks)
select x.Item,y.Item
from dbo.SplitStringVarcahr(#dataString, ':') x
cross apply
dbo.SplitStringVarcahr(x.Item,',') y
RETURN 0
As you already splitted into rows and you want insert into some table by splliting into two columns may be this works
CREATE TABLE #Test(ID INT,Val INT)
declare #t table (val varchar(50))
insert into #t (val)values ('1:20,2:30,4:50')
declare #str varchar(max)
;with cte as (
SELECT
Split.a.value('.', 'VARCHAR(100)') AS String
FROM (SELECT
CAST ('<M>' + REPLACE([val], ',', '</M><M>') + '</M>' AS XML) AS String
FROM #t) AS A CROSS APPLY String.nodes ('/M') AS Split(a))
INSERT INTO #Test
select SUBSTRING(String,0,CHARINDEX(':',String)),REVERSE(SUBSTRING(reverse(String),0,CHARINDEX(':',reverse(String)))) from cte
select * from #test
You can also try XML.nodes() and string functions to spit the data. Something like this
DECLARE #var VARCHAR(100) = '1:20,2:30,4:50'
DECLARE #xml xml = CONVERT(xml, '<r>' + REPLACE(#var,',','</r><r>') + '</r>')
SELECT LEFT(val,cindex - 1) c1,RIGHT(val,LEN(val) - cindex) c2
FROM
(
SELECT CHARINDEX(':',c.value('text()[1]','VARCHAR(100)')) cindex,c.value('text()[1]','VARCHAR(100)') val
FROM #xml.nodes('r') as t(c))c
Use substring and Charindex:
SELECT Substring(col, 0, Charindex(col, ':') - 1) AS id,
Substring(col, Charindex(col, ':') + 1, Len(col)-Charindex(col, ':')) AS value
FROM splittedtable

sql multiple row from column value

i have table with one column having comma seperated values and I want in row..
like
col1
3,4,5
5,6,6
return result should be
col1
3
4
5
5
6
6
declare #tbl table(data nvarchar(100))
insert into #tbl values('1,2,3')
insert into #tbl values('4,5,6')
insert into #tbl values('7,8,9')
SELECT
Split.a.value('.', 'VARCHAR(100)') AS String
FROM (SELECT data,
CAST ('<M>' + REPLACE(data, ',', '</M><M>') + '</M>' AS XML) AS String
FROM #tbl) AS A CROSS APPLY String.nodes ('/M') AS Split(a);
I believe the below explains how to loop through comma separated values. You could just insert them into another variable to get your required output.
Splitting of comma separated values
You can use a recursive query to perform this split:
;with cte (item, list) as
(
select
cast(left(col1, charindex(',',col1+',')-1) as varchar(50)) item,
stuff(col1, 1, charindex(',',col1+','), '') list
from yourtable
union all
select
cast(left(list, charindex(',',list+',')-1) as varchar(50)) item,
stuff(list, 1, charindex(',',list+','), '') list
from cte
where list > ''
)
select item
from cte
See SQL Fiddle with Demo