Xml Column Into Multiple Column With Separated Comma In Sql Server - sql

Using Sql Server 2012
I have table with single field within String containing xml format like below,
a
----
<data1>11</data1><data2>4</data2><data1>12</data1><data2>5</data2>
I want result table with containing separate comma for each column like this
data1|data2
-----------
11,12|4,5

Here's your script. Your a column is not a valid XML type, so i need to append as root element.
declare #strxml xml = concat('<t>', '<data1>11</data1><data2>4</data2><data1>12</data1><data2>5</data2>', '</t>')
SELECT
STUFF((SELECT ',' + b.dat.value('.', 'NVARCHAR(MAX)')
FROM tmp.node.nodes('data1') b (dat)
FOR XML PATH(''),TYPE).value('.', 'NVARCHAR(MAX)'),
1, 1, '') AS a,
STUFF((SELECT ',' + a.dat.value('.', 'NVARCHAR(MAX)')
FROM tmp.node.nodes('data2') a (dat)
FOR XML PATH(''),TYPE).value('.', 'NVARCHAR(MAX)'),
1, 1, '') AS b
FROM #strxml.nodes('/t') tmp(node);
applying your table. just replace test3 and yourcolumn
SELECT
STUFF((SELECT ',' + b.dat.value('.', 'NVARCHAR(MAX)')
FROM tmp.node.nodes('data1') b (dat)
FOR XML PATH(''),TYPE).value('.', 'NVARCHAR(MAX)'),
1, 1, '') AS a,
STUFF((SELECT ',' + a.dat.value('.', 'NVARCHAR(MAX)')
FROM tmp.node.nodes('data2') a ( dat )
FOR XML PATH(''),TYPE).value('.', 'NVARCHAR(MAX)'),
1, 1, '') AS b
FROM test3 t
CROSS APPLY (select cast(concat('<t>', yourcolumn, '</t>') AS xml)) as t1(X)
CROSS APPLY t1.X.nodes('t') AS tmp(node)

DECLARE #XMLData XML
SET #XMLData = '<a>
<data1>11</data1><data2>4</data2><data1>12</data1><data2>5</data2>
</a>'
SELECT REPLACE
(
#XMLData.query('data(a/data1)').value('.','varchar(100)')
,' ' -- replace the white spaces
,',' -- replace the white spaces with commas
) AS data1,
REPLACE
(
#XMLData.query('data(a/data2)').value('.','varchar(100)')
,' '
,','
) AS data2
OR
If you don't have any Root
DECLARE #XMLData XML
SET #XMLData = '
<data1>11</data1><data2>4</data2><data1>12</data1><data2>5</data2>
'
SELECT REPLACE
(
#XMLData.query('data(data1)').value('.','varchar(100)')
,' ' -- replace the white spaces
,',' -- replace the white spaces with commas
) AS data1,
REPLACE
(
#XMLData.query('data(data2)').value('.','varchar(100)')
,' '
,','
) AS data2
Note:-
1. First we have space separated value...
2. To fulfill our objective we can use Replace function to replace the spaces with comma's.

Related

how to insert a line break after every second loop in t-sql stuff function

how can i insert a CHAR(10) after every second loop in t-sql stuff function in my query
SELECT STUFF(
(
SELECT ', ' + new_name
FROM new_subcatagories
FOR XML PATH(''), TYPE
).value('.', 'VARCHAR(MAX)'), 1, 2, '')
so the result should by
record1,record2,
record3,record4
You could use a CASE expression to see if the value of ROW_NUMBER is divisible by 2, and if not then add a carriage return and line break:
SELECT STUFF((SELECT CASE WHEN ROW_NUMBER() OVER (order by new_nam) % 2 = 1 THEN CHAR(13) + CHAR(10) ELSE '' END + ', ' + new_nam
FROM new_subcatagories
ORDER BY new_nam
FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'), 1, 4, '');

sql server comma delimted string values into one row

I have a query that returns a row of multiple Itemcodes. The result is
Date group list of item code
2015-04-15 118 FYCT-00063,FYCM-00016,FYCM-00064,FYCF-00018
it's working fine but i need the result like this, with quotes around every code 'FYCT-00063','FYCM-00016','FYCM-00064','FYCF-00018'
The query is this:
SELECT DISTINCT SS.PostDate,SS.U_Unit,STUFF((
SELECT ', ',+ CAST(OWOR.ItemCode AS VARCHAR(10)) [text()]
FROM OWOR
WHERE OWOR.PostDate=SS.PostDate AND OWOR.U_Unit=SS.U_Unit AND OWOR.Status=SS.Status
FOR XML PATH('') , TYPE)
.value('.','NVARCHAR(MAX)'),1,2,' ') LISTGroup
from owor SS
Where SS.PostDate='15.APRIL.15' AND SS.U_Unit='Unit No 2' and SS.Status!='C'
SELECT DISTINCT SS.PostDate,SS.U_Unit,
STUFF((
SELECT ', ',+ '''' + CAST(OWOR.ItemCode AS VARCHAR(10) + '''') [text()]
FROM OWOR
WHERE OWOR.PostDate=SS.PostDate
AND OWOR.U_Unit=SS.U_Unit
AND OWOR.Status=SS.Status
FOR XML PATH('') , TYPE) .value('.','NVARCHAR(MAX)'),1,2,' ') LISTGroup
FROM owor SS
WHERE SS.PostDate='15.APRIL.15'
AND SS.U_Unit='Unit No 2'
AND SS.Status!='C'
Try this
SELECT DISTINCT SS.PostDate
,SS.U_Unit
,STUFF((
SELECT ', '
+ QUOTENAME(CAST(OWOR.ItemCode AS VARCHAR(10), ''''))
FROM OWOR
WHERE OWOR.PostDate = SS.PostDate
AND OWOR.U_Unit = SS.U_Unit
AND OWOR.STATUS = SS.STATUS
FOR XML PATH('')
).value('.', 'NVARCHAR(MAX)'), 1, 2, ' ') LISTGroup
FROM owor SS
WHERE SS.PostDate = '15.APRIL.15'
AND SS.U_Unit = 'Unit No 2'
AND SS.STATUS != 'C'
Try like this:
DECLARE #STRING varchar(max)
SELECT #STRING = 'FYCT-00063,FYCM-00016,FYCM-00064,FYCF-00018'
SELECT '''' + REPLACE(#STRING,',',''',''') + ''''
SQLFIDDLE DEMO
In your case it would be like
select distinct SS.PostDate,SS.U_Unit,'''' + REPLACE(STUFF((
SELECT ', ',+ CAST(OWOR.ItemCode AS VARCHAR(10)) [text()]
FROM OWOR
where OWOR.PostDate=SS.PostDate AND OWOR.U_Unit=SS.U_Unit AND OWOR.Status=SS.Status
FOR XML PATH('') , TYPE)
.value('.','NVARCHAR(MAX)'),1,2,' '),',',''',''') + '''' LISTGroup
from owor SS
Where SS.PostDate='15.APRIL.15' AND SS.U_Unit='Unit No 2' and SS.Status!='C'

SQL - Combine Multiple Columns with Multiple Rows into one row

What I'm trying to do:
I have records in a SQL table where there are 5 columns and thousands of rows.
The rows share duplicate data (i.e. account number) but what makes each unique is that data in one of the columns is different.
As an example:
col1|col2|col3|col4|col5
------------------------
123|abc|456|def|789
123|abc|456|def|date
But the columns can have different values, not necessarily always in column 5.
Here's what I started with:
SELECT TOP (15) stuff((
SELECT ', ' + te.[accountid]
,te.[char1]
,te.[date]
,te.[date2]
,te.[char2]
FROM D AS te
INNER JOIN D AS tue ON tue.[accountid] = te.[accountid]
WHERE tue.[accountid] = ue.[accountid]
FOR XML path('')
,type
).value('.', 'varchar(max)'), 1, 2, '') AS ifile
FROM D AS ue
GROUP BY ue.[accountid]
But I get a monster long string that includes the duplicate rows in one column. I'm not sure what else to try so any insight would be appreciated.
If I had to guess, you have an unnecessary self join in the subquery:
SELECT TOP (15) stuff((
SELECT ', ' + te.[accountid], te.[char1], te.[date], te.[date2], te.[char2]
FROM D te
WHERE te.[accountid] = ue.[accountid]
FOR XML path(''), type
).value('.', 'varchar(max)'), 1, 2, '') AS ifile
FROM D ue
GROUP BY ue.[accountid];
You might also want SELECT DISTINCT in the subquery.
Use UNION to get rid of all the duplicate values and use your FOR XML PATH on the output to append it to a single string:
SELECT TOP (15) stuff((
SELECT ', ' + CAST(te.[accountid] AS varchar(255)) FROM D
UNION
SELECT ', ' + CAST(te.[char1] AS varchar(255)) FROM D
UNION
SELECT ', ' + CAST(te.[date] AS varchar(255)) FROM D
UNION
SELECT ', ' + CAST(te.[date2] AS varchar(255)) FROM D
UNION
SELECT ', ' + CAST(te.[char2] AS varchar(255)) FROM D
FOR XML path('')
,type
).value('.', 'varchar(max)'), 1, 2, '') AS ifile
Untested, treat as pseudo-code to give the general idea.

SQL Declare Query only returns 1 row result

I'm trying to get a result from our db with one identifier (ArtNr) and one big chunk of text that also contains returns (Edit),
I also want the text from the (Edit) column to be stringed?
(like this: "texttexttext" it's the "" I need in the beginning and end of the text)
I have come up with the query below but it only gives 1 row in reply (should be like 4000) and it does of course not give me the Edit captioned with "" since I have no clue how to do it :)
Thanks in advance! /Christian
USE MSPes2t
DECLARE #result nvarchar(max) , #test nvarchar(255)
SELECT #result = AR.Edit , #test = AR.ArtNr
FROM DBO.AR
WHERE AR.ArtNr = '%'
ORDER BY AR.ArtNr
SELECT #test AS artnr,
#result AS edit
This is the result im searching for:
Like this:
ArtNr | Edit
------+----------------------------------------
12001 | "edit"
12002 | "edit"
28001 | "edit"
The following query should give you the desired results (although I am not exactly sure how you want to delimit your edits, I have used a semi-colon):
SELECT ArtNr = '12001',
Edit = STUFF(( SELECT ';"' + ar.Edit + '"'
FROM dbo.AR
WHERE AR.ArtNr = '12001'
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '');
A full explanation of how using the xml extension FOR XML PATH() works to concanate rows into a single field can be found in this answer
If you need to get the edits concatenated for more than one ArtNo then you could use somethig like:
SELECT ar.ArtNr,
Edit = STUFF(( SELECT ';"' + ar2.Edit + '"'
FROM dbo.AR AS ar2
WHERE AR2.ArtNr = ar.ArtNr
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM dbo.Ar
WHERE ar.ArtNr IN ('12001', '12002')
GROUP BY ar.ArtNr;
SIMPLE WORKING EXAMPLE
DECLARE #AR TABLE (ArtNr VARCHAR(5), Edit NVARCHAR(MAX));
INSERT #AR (ArtNr, Edit)
VALUES ('12001', 'editeditedit'), ('12001', 'edit2 edit2'),
('12001', 'edit3'), ('12002', 'edit2 edit2');
SELECT ar.ArtNr,
Edit = STUFF(( SELECT ';"' + ar2.Edit + '"'
FROM #AR AS ar2
WHERE AR2.ArtNr = ar.ArtNr
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM #AR AS ar
WHERE ar.ArtNr IN ('12001', '12002')
GROUP BY ar.ArtNr;
Gives:
ArtNr | Edit
------+----------------------------------------
12001 | "editeditedit";"edit2 edit2";"edit3"
12002 | "editeditedit"
EDIT
Based on your required output I think your query is as simple as concatenating " to either end of your edit field:
SELECT AR.ArtNr,
'"' + AR.edit + '"' AS Edit
FROM DBO.AR
WHERE AR.ArtNr = '%'
ORDER BY ArtNr;
In SQL Server 2012 and later you can use CONCAT but it doesn't offer much advantage in this scenario.

concatinate all rows of a column into single value

I have table called Rule.
RuleId Name
1 A1
2 A2
3 A3
.
.
.
Now I want all the names as single result.
may be like #allnames = A1,A2,A3
Can somebody advise how to write query for this without using loops?
Thanks in advance...
Try this:
SELECT #allnames = STUFF((SELECT distinct ',' + Name
FROM table1
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
, 1, 1, '');
SQL Fiddle Demo
DECLARE #names NVARCHAR(MAX)
SELECT #names = coalesce(#names + ',', '') + coalesce(Name, '')
FROM (SELECT distinct Name FROM Rule) x
print #names
Try this one -
DECLARE #temp TABLE ([RuleId] INT, Name CHAR(2))
INSERT INTO #temp([RuleId], Name)
VALUES
(1, 'A1'),
(2, 'A2'),
(3, 'A3')
DECLARE #all_names NVARCHAR(MAX)
SELECT #all_names = STUFF((
SELECT DISTINCT ',' + Name
FROM #temp
--ORDER BY Name
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
SELECT #all_names
Output -
---------------
A1,A2,A3