![](/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.