簡體   English   中英

遍歷臨時表以在SQL Server 2014中構建字符串的最佳方法

[英]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'

謝謝。

STUFFFOR 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('')),'&lt;','<'),'&gt;','>'),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中,對此有一個官方的聚合函數:

String_Agg

...但是那對你毫無用處。 抱歉。

您可以執行以下操作:

-- 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)
         ,'&lt;','<') -- replace this < with html code &lt;
         ,'&gt;','>') -- replace this > with html code &gt;
         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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM