Transpose comma seperated data into rows - some clarification - sql

Let say I have a data
ID String
-------------------
1 John, Adam
Based on the below query transpose comma seperated data into rows
SELECT A.[ID],
Split.a.value('.', 'VARCHAR(100)') AS String
FROM (SELECT [ID],
CAST ('<M>' + REPLACE([string], ',', '</M><M>') + '</M>' AS XML) AS String
FROM TableA) AS A CROSS APPLY String.nodes ('/M') AS Split(a);
Now, I would like to know what is the reason to have '.' and <M> in our query?
PN: Instead of flagging the post please let me know I will delete the post if it should not be post.

If you print out the string within the CAST, you will see that your text string has been turned into an XML string. The '.' in the split command is merely a location in which to start parsing the XML.

If it is sql server 2016 you can use string_split
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,',')

Related

Split values into separate rows

WITH Numbers AS (SELECT Table.ProductNumber FROM Table WITH (NOLOCK))
returns ProductNumber like 1, 2, 3,4,5 - some are comma separated, so I want to split and than do proper SELECT on them with WHERE
What I got so far is:
SELECT #XML = CONVERT(xml,'<root><s>' + REPLACE(Numbers , ',' ,'</s><s>') + '</s></root>')
SELECT [ProductNumber ] = T.c.value('.','varchar(60)') FROM #XML.nodes('/root/s') T(c)
But I dont know how to convert selected SQL resource Numbers into string for XML conversion and not loose track of which ProductNumber were in which row
The problem in your query is you are assigning the converted xml to a variable, but here only the last row will be stored in that variable.
Try something like this.
SELECT Split.a.value('.', 'VARCHAR(100)') splt_num
FROM (SELECT Cast ('<M>'
+ Replace(ProductNumber, ',', '</M><M>')
+ '</M>' AS XML) AS Data
FROM yourtable) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)

Splitting the data with comma separation in SQL Server

How to split the data in a column with comma separation?
I am attaching the images for my Input and my expecting output.
The following is the input:
enter link description here
The following is my expected output:
enter link description here
Please help me how I will get my required output with a SQL Server query
Thanks in advance,
Phani Kumar.
declare #t Table (ID INT,Groupname VARCHAR(10),Pid VARCHAR(20))
insert into #t (ID,Groupname,Pid)values (1,'xxxx','123,568,562,25')
insert into #t (ID,Groupname,Pid)values (2,'yyyy','2,356,321')
insert into #t (ID,Groupname,Pid)values (3,'zzzz','7,898,569')
insert into #t (ID,Groupname,Pid)values (4,'sss','12345')
SELECT ID,Groupname,
PARSENAME(REPLACE(Split.a.value('.', 'VARCHAR(100)'),'-','.'),1) 'Values'
FROM
(
SELECT ID,Groupname,
CAST ('<M>' + REPLACE([Pid], ',', '</M><M>') + '</M>' AS XML) AS Data
FROM #t
) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)

Getting latest data in a table from comma separated value joining with original table

I have created script to get the comma separated value, that value(cloumn1) joined with another table(column2), (column1) having n number of duplicate I want to get the latest top 1 from column1 and join with column2. script ->
SELECT A.EmailHistoryid,
Split.a.value('.', 'VARCHAR(100)') AS String,
A.MailTo
INTO #tmp
FROM (
SELECT EmailHistoryid,
CAST('<M>' + REPLACE([requestinstanceids], ',', '</M><M>') + '</M>' AS XML) AS String,
MailTo
FROM [emailhistoryDT] NOLOCK
) AS A
CROSS APPLY String.nodes('/M') AS Split(a)
ORDER BY a.EmailHistoryid DESC;

Splitting a variable length column in SQL server safely

I have a column (varchar400) in the following form in an SQL table :
Info
UserID=1123456,ItemID=6685642
The column is created via our point of sale application, and so I cannot do the normal thing of simply splitting it into two columns as this would cause an obscene amount of work. My problem is that this column is used to store attributes of products in our database, and so while I am only concerned with UserID and ItemID, there may be superfluous information stored here, for example :
Info
IrrelevantID=666,UserID=123124,AnotherIrrelevantID=1232342,ItemID=1213124.
What I want to retrieve is simply two columns, with no error given if neither of these attributes exists in the Info column. :
UserID ItemID
123124 1213124
Would it be possible to do this effectively, with error checking, given that the length of the IDs are all variable, but all of the attributes are comma-separated and follow a uniform style (i.e "UserID=number").
Can anyone tell me the best way of dealing with my problem ?
Thanks a lot.
Try this
declare #infotable table (info varchar(4000))
insert into #infotable
select 'IrrelevantID=666,UserID=123124,AnotherIrrelevantID=1232342,ItemID=1213124.'
union all
select 'UserID=1123456,ItemID=6685642'
-- convert info column to xml type
; with cte as
(
select cast('<info ' + REPLACE(REPLACE(REPLACE(info,',', '" '),'=','="'),'.','') + '" />' as XML) info,
ROW_NUMBER() over (order by info) id
from #infotable
)
select userId, ItemId from
(
select T.N.value('local-name(.)', 'varchar(max)') as Name,
T.N.value('.', 'varchar(max)') as Value, id
from cte cross apply info.nodes('//#*') as T(N)
) v
pivot (max(value) for Name in ([UserID], [ItemId])) p
SQL DEMO
You can try this split function: http://www.sommarskog.se/arrays-in-sql-2005.html
Assuming ItemID=1213124. is terminated with a dot.
Declare #t Table (a varchar(400))
insert into #t values ('IrrelevantID=666,UserID=123124,AnotherIrrelevantID=1232342,ItemID=1213124.')
insert into #t values ('IrrelevantID=333,UserID=222222,AnotherIrrelevantID=0,ItemID=111.')
Select
STUFF(
Stuff(a,1,CHARINDEX(',UserID=',a) + Len(',UserID=')-1 ,'' )
,CharIndex
(',',
Stuff(a,1,CHARINDEX(',UserID=',a) + Len(',UserID=')-1 ,'' )
)
,400,'') as UserID
,
STUFF(
Stuff(a,1,CHARINDEX(',ItemID=',a) + Len(',ItemID=')-1 ,'' )
,CharIndex
('.',
Stuff(a,1,CHARINDEX(',ItemID=',a) + Len(',ItemID=')-1,'' )
)
,400,'') as ItemID
from #t

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