Reputation: 1745
I am trying to string aggregate some data and am having an issue. This data will be used for a mail merge.
After I aggregate my data into a single column and then go to copy it into an email via mail merge the result looks like
Owner: Me, Pet: Dog, Other Pet: Cat, Pet2: Dog2, OtherPet2: Cat2
Owner: Me, Pet: Dog, Other Pet: Cat, Pet2: Dog2, OtherPet2: Cat2
Owner: Me, Pet: Dog, Other Pet: Cat, Pet2: Dog2, OtherPet2: Cat2
Owner: Me, Pet: Dog, Other Pet: Cat, Pet2: Dog2, OtherPet2: Cat2
I want each line to have the same indentation but I cannot currently achieve this trying a number of things.
My reproducible code is here:
DROP TABLE #Temp1
DROP TABLE #temp2
CREATE TABLE #Temp1 (Owner varchar(10), val1 varchar(10), val2 varchar(10), val3 varchar(10), val4 varchar(10))
INSERT INTO #Temp1 values('Me','Dog','Cat', 'Dog2', 'Cat2')
INSERT INTO #Temp1 values('You','Dog','Cat', 'Dog2', 'Cat2')
INSERT INTO #Temp1 values('He','Dog','Cat', 'Dog2', 'Cat2')
INSERT INTO #Temp1 values('She','Dog','Cat', 'Dog2', 'Cat2')
INSERT INTO #Temp1 values('Me','Dog','Cat', 'Dog2', 'Cat2')
INSERT INTO #Temp1 values('Me','Dog','Cat', 'Dog2', 'Cat2')
INSERT INTO #Temp1 values('Me','Dog','Cat', 'Dog2', 'Cat2')
SELECT Owner,
Pets =
cast(STUFF
(
(
SELECT (' '+ 'Owner: ' + Owner + ', Pet: ' + val1 + ', Other Pet: ' + val2 + ', Pet2: ' + cast(val3 as varchar)+ ', OtherPet2: ' + RTRIM(val4) + char(13))
FROM #Temp1 as b
WHERE b.Owner=a.Owner
FOR XML PATH(''),TYPE
).value('.', 'varchar(1000)'), 1, 1, '') as text)
INTO #Temp2
FROM #Temp1 as a
GROUP BY Owner
Order by Owner
SELECT * FROM #Temp2
The 2nd row for Owner "Me" would be the entry you can copy and paste to troubleshoot the indentation. What would I need to add to strip that extra space added at the beginning of my string concat?
Thank you
Upvotes: 2
Views: 3357
Reputation: 95989
This problem is your placement of CHAR(13)
. You want that at the start instead of the space:
SELECT Owner,
CAST(STUFF((SELECT (CHAR(13) + 'Owner: ' + Owner + ', Pet: ' + val1 + ', Other Pet: ' + val2 + ', Pet2: ' + CAST(val3 AS varchar) + ', OtherPet2: ' + RTRIM(val4) )
FROM #Temp1 AS b
WHERE b.Owner = a.Owner
FOR XML PATH(''), TYPE).value('.', 'varchar(1000)'),1,1,'') AS text) AS Pets
INTO #Temp2
FROM #Temp1 AS a
GROUP BY Owner
ORDER BY Owner;
STUFF
is only removing the first character of the entirety of the XML, not the first character of every delimited item created within the XML. CHAR(13)
is your delimiter here, not a whitespace (' '
), so put CHAR(13)
at the start instead.
When using the FOR XML PATH
and STUFF
method, the first character(s) are always your delimiters in the string. Then you use STUFF
to remove those characters from the first item. So, if you have a statement with a SELECT
with ',' + U.FirstName
, before STUFF
is applied you have the value ',Bob,Steve,Jane,Sally'
. The character you want to get rid of is the first delimiter; which is where STUFF
comes in. STUFF({FOR XML PATH},1,1,'')
takes the output from FOR XML PATH
, and then replaces 1 character, from position 1, with the value ''
. In ths example, it replaces ','
, making the final string 'Bob,Steve,Jane,Sally'
.
Upvotes: 6