Let's say I have an email feature and I need to select the recipients of an email.
users
table has columns: id
, full_name
emails
table has columns: id
, subject
, body
, sender_id
, recipient_id
Pseudo code is
SELECT
e.id AS email_id,
e.subject AS email_subject,
u_sender.full_name AS sender_name,
u_recipient.full_name AS recipient_name
FROM emails e
LEFT JOIN users u_sender
ON e.sender_id = u_sender.id
LEFT JOIN users u_recipient
ON e.recipient_id = u_recipient.id
This will return something like:
| email_id | email_subject | sender_name | recipient_name |
| 1 | Hello | John | Steve |
| 1 | Hello | John | Mark |
| 1 | Hello | John | Peter |
Instead, is there a way to get something like:
| email_id | email_subject | sender_name | recipient_name |
| 1 | Hello | John | [Steve, Peter, Mark] |
Notice that they have the same email_ids because my application can send the email to multiple recipients.
I found a similar question but the solution is apache-exclusive.
I also found a response that uses XML PATH here but it's for SQL Server 2005. I'm using postgres.
Thanks in advance.
PostgreSQL 9 provides the string_agg
aggregation function to flatten multiple values into a single string. In your example, it would be string_agg(u_recipient.full_name, ',')
along with a suitable group by
:
select
e.id email_id,
e.subject email_subject,
u_sender.full_name sender_name,
string_agg(u_recipient.full_name, ',') recipient_name
from emails e
left join users u_sender
on e.sender_id = u_sender.id
left join users u_recipient
on e.recipient_id = u_recipient.id
group by email_id, email_subject, sender_name
Use a GROUP BY clause with email_id, email_subject, sender_name and call STRING_AGG(recipient_name, ',')
You will have something like this:
SELECT email_id, email_subject, sender_name, string_agg(recipient_name, ',') FROM test GROUP BY email_id, email_subject, sender_name
With your query:
WITH X AS
(
SELECT
e.id AS email_id,
e.subject AS email_subject,
u_sender.full_name AS sender_name,
u_recipient.full_name AS recipient_name
FROM emails e
LEFT JOIN users u_sender
ON e.sender_id = u_sender.id
LEFT JOIN users u_recipient
ON e.recipient_id = u_recipient.id
)
SELECT email_id, email_subject, sender_name, string_agg(recipient_name, ',') FROM X GROUP BY email_id, email_subject, sender_name;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.