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 [email protected]
1 [email protected]
--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 [email protected]; [email protected]
1 [email protected]; [email protected]
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;
-----------------
[email protected], [email protected]
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