我在sql server数据库中有一个表,其中包含四列电子邮件地址,即Email1,Email2,Email3
和Email4
。我需要创建一个函数来返回合并的电子邮件地址并删除任何重复的电子邮件
(例如,Email1和Email3可能具有相同的地址email@email.com
,我只需要在组合字符串中包含一次)。
我编写了一个如下功能,它会返回组合值,但不确定我们如何删除重复的电子邮件。
Create FUNCTION [dbo].[CombineAndCommaSeparateEmails]
(@Email1 VARCHAR(250),@Email2 VARCHAR(250),@Email3 VARCHAR(250),@Email4 VARCHAR(250))
RETURNS VARCHAR(250)
AS BEGIN
DECLARE @combinedEmails VARCHAR(1000)
Set @combinedEmails=
concat(
Rtrim(Ltrim(Case when @EMAIL1 is not null then @EMAIL1+',' end)),
Rtrim(Ltrim(Case when @EMAIL2 is not null then @EMAIL2+',' end)),
Rtrim(Ltrim(Case when @EMAIL3 is not null then @EMAIL3+',' end)),
Rtrim(Ltrim(@EMAIL4)))
Set @combinedEmails= case
when RIGHT(@combinedEmails,1)=',' then substring(@combinedEmails,1,len(@combinedEmails)-1)
else @combinedEmails END
RETURN @combinedEmails
END
有什么想法吗?感谢
答案 0 :(得分:2)
您可以使用var array1 = ['a','b','c','d'];
var array2 = ['d','v','n','a','i','f'];
获取OUTER APPLY
电子邮件,之后只需使用任何方法将它们连接起来:
DISTINCT
此处我使用了STRING_AGG
,可以从SQL Server vNext获取。
答案 1 :(得分:2)
另一个选项(如果你想保留UDF)
Declare @EMail1 varchar(50) = 'some@email.com'
Declare @EMail2 varchar(50) = 'some@email.com'
Declare @EMail3 varchar(50) = 'someother@email.com'
Declare @EMail4 varchar(50) = 'some@email.com'
Select Stuff((Select Distinct ','+EMails From (values (@EMail1),(@EMail2),(@EMail3),(@EMail4) ) A (EMails) For XML Path('')),1,1,'')
返回
some@email.com,someother@email.com
作为功能
Create FUNCTION [dbo].[CombineAndCommaSeparateEmails] (@Email1 VARCHAR(250),@Email2 VARCHAR(250),@Email3 VARCHAR(250),@Email4 VARCHAR(250))
Returns varchar(250)
AS
BEGIN
Return (
Select Stuff((Select Distinct ','+EMails
From (values (@EMail1)
,(@EMail2)
,(@EMail3)
,(@EMail4)
) A (EMails)
Where EMails<>''
For XML Path('')),1,1,'')
)
End
所以
Select [dbo].[CombineAndCommaSeparateEmails]('some@email.com','some@email.com','someother@email.com',null)
返回
some@email.com,someother@email.com
答案 2 :(得分:1)
使用一些虚拟测试数据:
CREATE TABLE people (
ID INT,
Name VARCHAR(50),
Email1 VARCHAR(50),
Email2 VARCHAR(50),
Email3 VARCHAR(50),
Email4 VARCHAR(50)
)
INSERT INTO people (ID, Name, Email1, Email2, Email3, Email4) VALUES
(1, 'John Smith', 'jsmith@gmail.com', 'johns@work.com', '', 'jsmith@gmail.com'),
(2, 'Jane Doe', 'janedoe2001@gmail.com', 'janed@business.com', '', ''),
(3, 'Roger White', 'rwhite@gmail.com', 'whitey@somewhere.com', 'rwhite@gmail.com', 'rwhite@gmail.com');
我创建了一个CTE来返回所有唯一的电子邮件地址,然后使用FOR XML PATH
将它们合并:
WITH uniqueEmails (ID, Name, Email) AS
(
SELECT ID, Name, Email1 AS Email
FROM people
UNION
SELECT ID, Name, Email2 AS Email
FROM people
UNION
SELECT ID, Name, Email3 AS Email
FROM people
UNION
SELECT ID, Name, Email4 AS Email
FROM people
)
SELECT DISTINCT
e.ID,
e.Name,
STUFF(
(
SELECT ',' + e2.Email
FROM uniqueEmails e2
WHERE e2.ID = e.ID
AND ISNULL(e2.Email,'') <> ''
GROUP BY e2.Email
ORDER BY e2.Email
FOR XML PATH('')
), 1, 1, ''
) AS Emails
FROM uniqueEmails e
WHERE ISNULL(e.Email,'') <> ''
对于上面的测试数据,这会得到以下结果:
/-------------------------------------------------------------\
| ID | Name | Emails |
|----+-------------+------------------------------------------|
| 1 | John Smith | johns@work.com,jsmith@gmail.com |
| 2 | Jane Doe | janed@business.com,janedoe2001@gmail.com |
| 3 | Roger White | rwhite@gmail.com,whitey@somewhere.com |
\-------------------------------------------------------------/
答案 3 :(得分:0)
首先使用CROSS APPLY和VALUES删除重复项,然后使用XML PATH STUFF将其重新组合在一起。
DROP TABLE #TMP
CREATE TABLE #TMP (ID INT
,Text1 VARCHAR(255)
,Text2 VARCHAR(255)
,Text3 VARCHAR(255)
,Text4 VARCHAR(255)
)
INSERT INTO #TMP VALUES
(1,'aaa','bbb','ccc','ddd')
,(2,'fff','ggg','fff','hhh') --Row With Duplicate
;WITH cte_UP --Remove Duplicates Using an unpivot CROSS APPLY with VALUES
AS
(
SELECT DISTINCT
T.ID
,U.Textn
FROM
#TMP T CROSS APPLY (VALUES (T.Text1)
,(T.Text2)
,(T.Text3)
,(T.Text4))
U(Textn)
)
--USE XML STUFF TO CONCATENATE UNIQUE VALUES
SELECT
ID,
STUFF((
SELECT ','+ cast(Textn AS NVARCHAR(255))
FROM cte_UP b
WHERE a.ID = b.ID
FOR XML PATH('')
)
,1,1,'') AS TextN
FROM cte_UP a
GROUP BY a.ID