![](/img/trans.png)
[英]Iterate through rows and insert data in temp table - SQL Server 2008
[英]Best way to Iterate through temp table to build string in SQL Server 2014
我已经创建了一个临时表,这个想法是我想遍历该表,用相同的电子邮件地址匹配所有记录,然后填充一个字符串,该字符串将进入电子邮件,然后删除该表。 这将作为存储过程运行。
我曾经使用过一个游标,该游标首先获取所有唯一的电子邮件地址,然后合并记录,但可能无法接受10万至50万条记录的性能,而且我知道必须有一种效率更高的方法。
示例数据(抱歉,不知道如何正确格式化)
#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
然后,我想用此数据填充另一个表
emailto... emailbody
test@test.com 'string1<br / > string2'
test2@test.com 'string3<br / > string4'
test3@test.com 'string5'
谢谢。
STUFF
和FOR XML PATH
方法可以在SQl Server 2014及更高版本中很好地实现此目的。 因为您有字符<
和>
,但是之后需要将它们“转义”:
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;
您不需要使用游标,请使用string_agg函数。
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
在SQL Server 2014中,有多种方法可以实现,而无需使用游标,但是从根本上讲,它们是相当复杂的hack,在我看来,这导致了非常难以理解的SQL。 详细信息请参见此处:
如何在SQL Server中将多行文本合并为单个文本字符串?
游标可以说是SQL 2014中最好的方式,因为至少它是可读的。
在Sql Server 2017中,对此有一个官方的聚合函数:
...但是那对你毫无用处。 抱歉。
您可以执行以下操作:
-- 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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.