I have created a temp table, the idea being that I want to loop through it, match all records with the same email address and then populate a string, which will go in to an email, then drop the table. This will be run as a stored procedure.
I've used a cursor that first grabbed all the unique email addresses and then coalesce the records but with potentially 100k-500k records performance won't be acceptable, and I know there must be a far more efficient way of doing it.
Example data (apologies, don't know how to format it properly)
#temptable
temp_email, temp_string
test@test.com string1
test@test.com string2
test2@test.com string3
test2@test.com string4
test3@test.com string5
I then want to populate another table with this data
emailto... emailbody
test@test.com 'string1<br / > string2'
test2@test.com 'string3<br / > string4'
test3@test.com 'string5'
Thank you.
The STUFF
and FOR XML PATH
method achieves this nicely in SQl Server 2014 and prior. Because you have the characters <
and >
however, they need to be "un-escaped" afterwards:
WITH VTE AS(
SELECT *
FROM (VALUES('test@test.com','string1'),
('test@test.com','string2'),
('test2@test.com','string3'),
('test2@test.com','string4'),
('test3@test.com','string5')) V(Email, String))
SELECT Email,
STUFF(REPLACE(REPLACE((SELECT '<br/>' + sq.String
FROM VTE sq
WHERE sq.Email = V.Email
FOR XML PATH('')),'<','<'),'>','>'),1,5,'')
FROM VTE V
GROUP BY Email;
you dont need to use cursor, please use string_agg function.
Create table #temptable
(temp_email varchar(50), temp_string varchar(50))
INSERT INTO #temptable
VALUES ('test@test.com', 'string1'),
('test@test.com', 'string2'),
('test2@test.com', 'string3'),
('test2@test.com', 'string4'),
('test3@test.com', 'string5')
Select temp_email, STRING_AGG(temp_string,' <br/>')
from #temptable
Group by temp_email
In SQL Server 2014 there are ways of doing this without a cursor but they are basically quite convoluted hacks and lead to pretty unreadable SQL in my opinion. See here for details:
How to concatenate text from multiple rows into a single text string in SQL server?
A cursor is arguably the best way in SQL 2014 because at least its readable.
In Sql Server 2017 there is an official aggregation function for this:
... but thats no use to you at the mo. Sorry.
You can do something like this :
-- Create temp table
CREATE TABLE #temptable (temp_email varchar(50), temp_string varchar(50))
-- populate table with data
INSERT INTO #temptable
VALUES ('test@test.com', 'string1'),
('test@test.com', 'string2'),
('test2@test.com', 'string3'),
('test2@test.com', 'string4'),
('test3@test.com', 'string5')
-- actual query
;WITH CTE_table AS(
SELECT C.temp_email,
REPLACE(REPLACE(STUFF(
(SELECT CAST(temp_string AS VARCHAR(20))+'<br/>' AS [text()]
FROM #temptable AS O
WHERE C.temp_email= o.temp_email
FOR XML PATH('')), 1, 0, NULL)
,'<','<') -- replace this < with html code <
,'>','>') -- replace this > with html code >
AS temp_string
,ROW_NUMBER() OVER (partition by temp_email order by temp_email) rownumber
FROM #temptable AS C
)
-- Get only unique records
SELECT temp_email,temp_string FROM CTE_table
Where rownumber=1
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.