How to create a MS SQL Query that will include a concatenation of data from another table based on id into a single column

I am writing a script to export exchange message tracking information into SQL so it can be queried by an analyst.
I stored the a 4 tables
messagelog, contacts, event, messagerecipients.
I am trying to build a query that will produce a separate row for each recipient and another query that will combine all the recipients into a comma separated list into one column. Any guidance/answers?

I store each email only once in the contacts table and the event type (SEND,RECEIVE...) once in the event table.

The messagelog table is as follows:
id,eventid,sender,subject,exmessageid,time

I have a messagerecipients table that is a map of recipients to messagelog:
id,contactid,messagelogid

Table data

--contacts
id      email
21      externaluser@domain.com
19      noreply@domain.com
17      noreply@email.education.com
13      noreply2@domain.com
23      person1@somewhere.com
24      person2@somewhere.com
25      person3@somewhere.com
22      staff.five@example.com
16      staff.four@example.com
14      staff.one@example.com
18      staff.six@example.com
15      staff.three@domain.com
20      staff.two@example.com

--event
id      type
1      BADMAIL
2      DELIVER
3      DSN
4      FAIL
5      POISONMESSAGE
6      EXPAND
7      RECEIVE
8      RESOLVE
9      SEND
10      SUBMIT
11      TRANSFER

--messagelog
id      eventid      sender      subject      exmessageid            time
1            7            13                                    8325692                  2018-02-10 16:00:12.000
2            7            15                                    8325693                  2018-02-10 16:03:11.000
3            7            17                                    8325694                  2018-02-10 16:03:55.000
4            7            19                                    8325695                  2018-02-10 16:04:04.000
5            7            21                                    8325696                  2018-02-10 16:05:07.000

--messagerecipients
id      contactid      messagelogid
1      14                  1
2      16                  2
3      18                  3
4      20                  4
5      22                  5
6      23                  3
7      24                  4
8      25                  5
LVL 2
byt3Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

byt3Author Commented:
Okay, so I figured out the row per recipient query, still working on the query with all recipients concatenated into one column. Here's the query I built. If there is a better way to do it, let me know.

SELECT ml.EventID,ml.Sender,r.email AS Recipient,ml.Subject,ml.ExMessageID,ml.Time FROM messagerecipients
LEFT JOIN (SELECT m.id,e.type AS EventID,c.email AS Sender,m.subject AS Subject,m.exmessageid AS ExMessageID,m.time AS TIME FROM messagelog m LEFT JOIN event e ON e.id=m.eventid LEFT JOIN contacts c ON c.id=m.sender) ml 
ON ml.id=messagerecipients.messagelogid
LEFT JOIN contacts r ON messagerecipients.contactid=r.id

Open in new window

0
Jim HornMicrosoft SQL Server Developer, Architect, and AuthorCommented:
Here's a code and image heavy demo on how to pull that off, written in 2008R2 so it may not reflect everything now in 2017. T-SQL:  Normalized data to a single comma delineated string and back
0
Arifhusen AnsariBusiness Intelligence Developer and AnalystCommented:
Hello,

You can try below query as well. It will give you details in single raw as well as combined approach.

SELECT
	msglog.id
	,evt.type
	,LTRIM(RTRIM(sender.Email)) Sender
	,LTRIM(RTRIM(rec.Email)) Recipient
	,msglog.subject
	,msglog.exmessageid
	,msglog.time
	
INTO #Tmp
FROM messagerecipients t1
INNER JOIN contacts rec 
ON t1.contactid =rec.ID 
INNER JOIN messagelog msglog
ON msglog.id=t1.messagelogid
INNER JOIN contacts sender
ON sender.ID=msglog.sender
INNER JOIN event evt
ON evt.ID=msglog.eventid



SELECT DISTINCT
	ID
	,Sender
	,subject
	,exmessageid
	,time
	,STUFF(col1,1,1,'') AS Recipient
FROM #tmp t1

CROSS APPLY ( SELECT ( SELECT ','+ Recipient  FROM #Tmp WHERE id =t1.id  FOR XML PATH('')) AS col1 ) AS M

DROP TABLE #Tmp

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Mark WillsTopic AdvisorCommented:
Can also try :
SELECT distinct e.type as EventID ,c.email as Sender,l.Subject,l.ExMessageID,l.Time 
     ,stuff((select ','+ r.email from messagerecipients mr inner JOIN contacts r ON mr.contactid=r.id where l.id=mr.messagelogid for XML path('')),1,1,'') recipients 
FROM messagerecipients m
LEFT JOIN messagelog l on l.id=m.messagelogid
LEFT JOIN event e ON e.id=l.eventid 
LEFT JOIN contacts c ON c.id=l.sender 

Open in new window

0
byt3Author Commented:
Thanks, all the information was great the the queries work perfectly.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Exchange

From novice to tech pro — start learning today.