简体   繁体   English

SQL如何将行“收集”成单行

[英]SQL how to “collect” rows into a single row

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 users表具有以下列: idfull_name

emails table has columns: id , subject , body , sender_id , recipient_id emails表中的列: idsubjectbodysender_idrecipient_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_id | email_subject | email_subject | sender_name | sender_name | recipient_name | 收件人名称|
| | 1 | 1 | Hello | 你好 John | 约翰| Steve | 史蒂夫
| | 1 | 1 | Hello | 你好 John | 约翰| Mark | 马克|
| | 1 | 1 | Hello | 你好 John | 约翰| Peter | 彼得|

Instead, is there a way to get something like: 相反,有没有办法得到类似的东西:
| | email_id | email_id | email_subject | email_subject | sender_name | sender_name | recipient_name | 收件人名称|
| | 1 | 1 | Hello | 你好 John | 约翰| [Steve, Peter, Mark] | [史蒂夫,彼得,马克] |

Notice that they have the same email_ids because my application can send the email to multiple recipients. 请注意,它们具有相同的email_id,因为我的应用程序可以将电子邮件发送给多个收件人。

I found a similar question but the solution is apache-exclusive. 我发现了一个类似的问题,但是解决方案是针对Apache的。

I also found a response that uses XML PATH here but it's for SQL Server 2005. I'm using postgres. 我还发现,使用XML PATH的响应这里 ,但它是SQL Server 2005中,我使用的是Postgres。

Thanks in advance. 提前致谢。

PostgreSQL 9 provides the string_agg aggregation function to flatten multiple values into a single string. PostgreSQL 9提供了string_agg聚合函数,可以将多个值展平为单个字符串。 In your example, it would be string_agg(u_recipient.full_name, ',') along with a suitable group by : 在您的示例中,它将是string_agg(u_recipient.full_name, ',')以及合适的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, ',') 将GROUP BY子句与email_id,email_subject,sender_name一起使用,并调用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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM