Multiple rows in one column SQL Server

℡╲_俬逩灬. 提交于 2019-12-02 01:52:39

问题


I want to concatenate multiple rows in one column. I found many examples in Internet but does not working for me. What am I doing wrong?

        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

I'm still having the information like this

UserID  Email
1       abc@yahoo.com
1       cde@gmail.com 

--EDIT--

Ok, I did this change but still having 2 rows. If I apply distinct this will fix my problem but why do I have to use distinct. The query must group it by itself.

        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

Results

UserID   Email 
1        abc@yahoo.com; cde@gmail.com
1        abc@yahoo.com; cde@gmail.com

回答1:


Unfortunately, SQL Server doesn't have proper string concatenation, so you cannot concatenate strings while grouping. So there're several possible solutions.

1. If you want to concatenate data for single ID, you can use variable trick:

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

2. If you want to do proper grouping, you can use xml trick. So, basic idea is - you get distinct UserID as anchor query (using group by), and then concatenate data in the subquery. Important thing is to do this correctly, use for xml ... type and get concatenated string as .value(), so special characters will be treated correctly:

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

See sql fiddle demo with examples: sql fiddle demo




回答2:


The entire sub query inside the STUFF() function is evaluated for each row that meets the criteria in the where clause.

In this case you seem to have two rows with ID of 1.

Since the results you want are for the entire set, each row in that set will have the same results, so selecting distinct just helps you hide the duplicates.

If you format your query like this, it will be easier to see why this happens:

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,
    ue.Email
From UserEmail ue
where UserID = 1


来源:https://stackoverflow.com/questions/20057655/multiple-rows-in-one-column-sql-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!