SQL Server中的一列中有多行

Max*_*mus 2 xml sql-server concatenation path sqlxml

我想在一列中连接多个行.我在互联网上找到了很多例子,但对我不起作用.我究竟做错了什么?

        SELECT UserID,  
        STUFF((SELECT '; ' + Email.Email From Email where  UserEmail.EmailID = Email.ID for xml path('')),1,1, '') AS Emails
        From UserEmail
        where UserID = 1
Run Code Online (Sandbox Code Playgroud)

我仍然有这样的信息

UserID  Email
1       abc@yahoo.com
1       cde@gmail.com 
Run Code Online (Sandbox Code Playgroud)

- 编辑 -

好的,我做了这个改变,但仍然有2行.如果我应用distinct,这将解决我的问题,但为什么我必须使用distinct.查询必须自行分组.

        SELECT UserID,  
        STUFF(( SELECT '; ' + ea.Email 
                From Email ea inner join UserMail ue_inner on ue_inner.EmailID = ea.ID 
                where 
                ue_inner.UserID = ue.UserID
                for xml path('')), 1, 1, '') 
                AS Email
        From UserEmail ue
        where UserID = 1
Run Code Online (Sandbox Code Playgroud)

结果

UserID   Email 
1        abc@yahoo.com; cde@gmail.com
1        abc@yahoo.com; cde@gmail.com
Run Code Online (Sandbox Code Playgroud)

Rom*_*kar 5

遗憾的是,SQL Server没有正确的字符串连接,因此在分组时无法连接字符串.所以有几种可能的解决方案.

1.如果要连接单个ID的数据,可以使用变量技巧:

declare @Emails varchar(max)

select @Emails = isnull(@Emails + ', ', '') + E.Email
from Email as E
    inner join UserEmail as UE on UE.EmailID = E.EmailID
where UE.UserID = 1

select @Emails;

-----------------
abc@yahoo.com, cde@gmail.com
Run Code Online (Sandbox Code Playgroud)

2.如果要进行正确的分组,可以使用xml技巧.因此,基本思路是 - 您将不同的UserID作为锚点查询(使用group by),然后在子查询中连接数据.重要的是要正确执行此操作,使用for xml ... type并获取连接字符串.value(),因此将正确处理特殊字符:

select
    UE.UserID,
    stuff(
        (
            select ', ' + TE.Email
            from Email as TE
                inner join UserEmail as TUE on TUE.EmailID = TE.EmailID
            where TUE.UserID = UE.UserID
            for xml path(''), type
        ).value('.', 'varchar(max)')
    , 1, 2, '') as Emails
from UserEmail as UE
group by UE.UserID
Run Code Online (Sandbox Code Playgroud)

请参阅sql小提琴演示与示例: sql fiddle demo