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

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, '');

Related

Xml Column Into Multiple Column With Separated Comma In Sql Server

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.

& instead of & in STUFF FOR XML PATH

I am using STUFF function. I have some entries having & but shows &amp ; instead. Somewhere I read that & is reserved in XML. How to solve this.
...STUFF((SELECT (', ' + CategoryName) FROM CategoryTable WHERE CategoryId IS NOT NULL AND CategoryId IN (1,2,3) FOR XML PATH('')), 1, 1, '') as CategoryName,...
Above is my query (Well I have just added a part of a full query.). How to solve. Thanks.
The wrong way:
SELECT STUFF(
(
SELECT ', ' + v.name
FROM (
VALUES
('bonnie & clyde'),
('thelma & louise')
)v(NAME)
FOR XML PATH('')
), 1, 2, '')
The jedi path:
SELECT STUFF(
(
SELECT ', ' + v.name
FROM (
VALUES
('bonnie & clyde'),
('thelma & louise')
)v(NAME)
FOR XML PATH(''), TYPE
).value('.', 'VARCHAR(MAX)'), 1, 2, '')
Use this ..
FOR XML PATH(''),TYPE).value('.','NVARCHAR(MAX)')

Stuff query in SQL Server

SELECT DISTINCT
AcNumber,
(SELECT STUFF((SELECT '::' + (REPLACE(RTRIM(LTRIM([master].dbo.Mig_fn_cutString([master].dbo.Mig_fn_StringReduce(UPPER(NomiName)),35,',',1,'Y','F'))),',',' '))
FROM [DepNominee] DPN
WHERE (AcNumber = DPN.AcNumber)
FOR XML PATH(''), TYPE).value('(./text())[1]', 'VARCHAR(MAX)'), 1, 2, '')) AS JBL_NOM_NAME,
(SELECT STUFF((SELECT '::' + (REPLACE(RTRIM(LTRIM([master].dbo.Mig_fn_cutString([master].dbo.Mig_fn_StringReduce(UPPER(FHName)),35,',',1,'Y','F'))),',',' '))
FROM [DepNominee] DPN
WHERE (AcNumber = DPN.AcNumber)
FOR XML PATH(''),TYPE).value('(./text())[1]', 'VARCHAR(MAX)'), 1, 2, '')) AS NOM_FATH_NAME,
(SELECT STUFF((SELECT '::' + (REPLACE(RTRIM(LTRIM([master].dbo.Mig_fn_cutString([master].dbo.Mig_fn_StringReduce(UPPER(MHName)),35,',',1,'Y','F'))),',',' '))
FROM [DepNominee] DPN
--WHERE (AcNumber = DPN.AcNumber)
FOR XML PATH(''),TYPE).value('(./text())[1]', 'VARCHAR(MAX)'), 1, 2, '')) AS NOM_MOTH_NAME
FROM
[DepNominee] DPN
GROUP BY
AcNumber, NomiName
That is my code, I want to see all data according my AccountNumber. But I see only one data repeating all the time in different account number. I attach the image:
I suspect the problem is that you are using the alias DPN in more than one place, causing your subqueries not to be correlated.
Try it like this:
SELECT DISTINCT
AcNumber,
(SELECT STUFF((SELECT '::' + (REPLACE(RTRIM(LTRIM([master].dbo.Mig_fn_cutString([master].dbo.Mig_fn_StringReduce(UPPER(NomiName)),35,',',1,'Y','F'))),',',' '))
FROM [DepNominee] DPN2
WHERE (DPN.AcNumber = DPN2.AcNumber)
FOR XML PATH(''), TYPE).value('(./text())[1]', 'VARCHAR(MAX)'), 1, 2, '')) AS JBL_NOM_NAME,
(SELECT STUFF((SELECT '::' + (REPLACE(RTRIM(LTRIM([master].dbo.Mig_fn_cutString([master].dbo.Mig_fn_StringReduce(UPPER(FHName)),35,',',1,'Y','F'))),',',' '))
FROM [DepNominee] DPN2
WHERE (DPN.AcNumber = DPN2.AcNumber)
FOR XML PATH(''),TYPE).value('(./text())[1]', 'VARCHAR(MAX)'), 1, 2, '')) AS NOM_FATH_NAME,
(SELECT STUFF((SELECT '::' + (REPLACE(RTRIM(LTRIM([master].dbo.Mig_fn_cutString([master].dbo.Mig_fn_StringReduce(UPPER(MHName)),35,',',1,'Y','F'))),',',' '))
FROM [DepNominee] DPN2
--WHERE (DPN.AcNumber = DPN2.AcNumber)
FOR XML PATH(''),TYPE).value('(./text())[1]', 'VARCHAR(MAX)'), 1, 2, '')) AS NOM_MOTH_NAME
FROM
[DepNominee] DPN
GROUP BY
AcNumber, NomiName

many rows into a single column with SQL

I have an one to many table, and if there is rows that have same reference id(Paragraph ID) I want to concatenate so LoginName value have many in same row.
This query does what I want it to do but there is a problem, It replaces first char. the STUFF function requires a replace value.
My question:
How can I do this without replacing first char?
SELECT DISTINCT
ParagraphID
, STUFF((
SELECT N'|' + CAST([LoginName] AS VARCHAR(255))
FROM [dbo].[CM_Signature] f2
WHERE f1.ParagraphID = f2.ParagraphID
FOR XML PATH ('')), 1, 2, '') AS FileNameString
FROM [dbo].[CM_Signature] f1
Expected value:
Daniel | Emma
Here is what you can use:
SELECT DISTINCT
ParagraphID
, STUFF((
SELECT N' | ' + CAST([LoginName] AS VARCHAR(255))
FROM [dbo].[CM_Signature] f2
WHERE f1.ParagraphID = f2.ParagraphID
FOR XML PATH ('')), 1, 1, '') AS FileNameString
FROM [dbo].[CM_Signature] f1
Note the STUFF("...", 1, 1, '') instead of STUFF("...", 1, 2, '').
Because you need to replace 1 char instead of 2 (To remove the first |).
Output:
Daniel|Emma
Also, if you want to have spaces before and after the |, just use this query:
SELECT DISTINCT
ParagraphID
, STUFF((
SELECT N' | ' + CAST([LoginName] AS VARCHAR(255))
FROM [dbo].[CM_Signature] f2
WHERE f1.ParagraphID = f2.ParagraphID
FOR XML PATH ('')), 1, 3, '') AS FileNameString
FROM [dbo].[CM_Signature] f1
Note that this time we removed 3 chars (STUFF("...", 1, 3, '')).
Output:
Daniel | Emma
You were starting your path at position 2 instead of first
SELECT DISTINCT
ParagraphID
, STUFF((
SELECT N'|' + CAST([LoginName] AS VARCHAR(255))
FROM [dbo].[CM_Signature] f2
WHERE f1.ParagraphID = f2.ParagraphID
FOR XML PATH ('')), 1, 1, '') AS FileNameString
FROM [dbo].[CM_Signature] f1 SELECT DISTINCT
ParagraphID
, STUFF((
SELECT N'|' + CAST([name] AS VARCHAR(255))
FROM mytable f2
WHERE f1.paragraphid = f2.paragraphid
FOR XML PATH ('')), 1, 1, '') AS FileNameString
FROM mytable f1
Use this Code:
create table #test (paragraghid int,name VARCHAR(10))
insert into #test values(1929,'Daniel')
insert into #test values(1929,'Emma')
insert into #test values(1935,'Daniel')
select distinct paragraghid,STUFF((select ' | ' + name from #test a
Where a.paragraghid=b.paragraghid for XML PATH('') ),1,2,'') as FilenameString
from #test b
You can write a query as:
DECLARE #CM_Signature table
(
RowId int,
ParagraphID int,
LoginName varchar(10))
Insert into #CM_Signature values
(4,1929,' Daniel'),
(5,1929,' Emma '),
(6,1935,'Daniel')
SELECT DISTINCT
ParagraphID
, STUFF((
SELECT N'| ' + CAST(rtrim(ltrim([LoginName])) AS VARCHAR(255))
FROM #CM_Signature f2
WHERE f1.ParagraphID = f2.ParagraphID
FOR XML PATH ('')), 1, 1, '') AS FileNameString
FROM #CM_Signature f1

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.