【问题标题】:PostgreSQL 9.1: How to concatenate rows in array without duplicates, JOIN another tablePostgreSQL 9.1:如何连接数组中的行而不重复,加入另一个表
【发布时间】:2012-09-04 03:11:30
【问题描述】:

我使用的是 PostgreSQL 9.1,需要帮助将多行合并为一个。我需要在 2 张桌子上做到这一点。当我使用两次array_agg() 函数时,结果中出现重复值。

表格:

CREATE TABLE rnp (id int, grp_id int, cabinets varchar(15) );

INSERT INTO rnp VALUES
 (1,'11','cabs1')
,(2,'11','cabs2')
,(3,'11','cabs3')
,(4,'11','cabs4')
,(5,'22','c1')
,(6,'22','c2');

CREATE TABLE ips (id int, grp_id int, address varchar(15));

INSERT INTO ips VALUES
 (1,'11','NY')
,(2,'11','CA')
,(3,'22','DC')
,(4,'22','LA');

SQL:

SELECT DISTINCT

  rnp.grp_id,
  array_to_string(array_agg(rnp.cabinets)OVER (PARTITION BY rnp.grp_id), ',') AS cabinets,
  array_to_string(array_agg(ips.address) OVER (PARTITION BY ips.grp_id), ',') AS addresses


FROM rnp JOIN ips ON rnp.grp_id=ips.grp_id

结果:

GRP_ID  CABINETS                                             ADDRESSES
11  cabs1,cabs1,cabs2,cabs2,cabs3,cabs3,cabs4,cabs4     NY,CA,NY,CA,NY,CA,NY,CA
22  c1,c1,c2,c2                                             DC,LA,DC,LA

而我需要的是:

 GRP_ID     CABINETS                 ADDRESSES
    11  cabs1,cabs2,cabs3,cabs4       NY,CA,
    22  c1,c2                         DC,LA

SQLFiddle 中的这个例子:http://sqlfiddle.com/#!1/4815e/19

一张表没问题-SQLFiddle:http://sqlfiddle.com/#!1/4815e/20

我错过了什么?由于JOIN,是否有可能做到这一点?

【问题讨论】:

  • 如果我能给出 +5 的好问题,我会的。指定版本、测试数据、预期结果、尝试查询。做得很好。

标签: sql postgresql postgresql-9.1


【解决方案1】:

不要使用窗口函数和分区,而是使用查询级别的 GROUP BY 并使用 DISTINCT 子句进行聚合:

SELECT         
  rnp.grp_id,
  array_to_string(array_agg(distinct rnp.cabinets),',') AS cabinets,
  array_to_string(array_agg(distinct ips.address),',')  AS addresses
FROM rnp JOIN ips ON rnp.grp_id=ips.grp_id GROUP BY rnp.grp_id, ips.grp_id;

结果:

 grp_id |        cabinets         | addresses 
--------+-------------------------+-----------
     11 | cabs1,cabs2,cabs3,cabs4 | CA,NY
     22 | c1,c2                   | DC,LA
(2 rows)

这里的关键是,您使用查询级别的GROUP BY 并使用DISTINCT 子句聚合,而不是使用窗口函数和分区。

这也适用于窗口函数方法,只是 PostgreSQL(至少 9.1)不支持窗口函数中的 DISTINCT

regress=# SELECT DISTINCT
  rnp.grp_id,
  array_to_string(array_agg(distinct rnp.cabinets)OVER (PARTITION BY rnp.grp_id), ',') AS cabinets,                    
  array_to_string(array_agg(distinct ips.address) OVER (PARTITION BY ips.grp_id), ',') AS addresses
FROM rnp JOIN ips ON rnp.grp_id=ips.grp_id;
ERROR:  DISTINCT is not implemented for window functions
LINE 3:   array_to_string(array_agg(distinct rnp.cabinets)OVER (PART...

【讨论】:

  • 是的!!!!伟大的!!!!太感谢了!我浪费了一整天的时间,你在一分钟内给了我结果! :)
  • @lana80 有时,当您整天盯着同一个问题时,您需要的只是一双全新的眼睛。很高兴能提供帮助。
猜你喜欢
  • 2016-12-09
  • 2018-02-28
  • 1970-01-01
  • 1970-01-01
  • 2021-10-10
  • 2019-01-06
  • 2023-03-26
  • 2013-10-04
  • 1970-01-01
相关资源
最近更新 更多