2012-09-11 12 views
27

私はPostgreSQL 9.1を使用しており、複数の行を1つに連結するのに役立つ必要があります。私は2つのテーブルでそれを行う必要があります。 2回使用すると、結果に重複した値が得られます。array_agg()PostgreSQL 9.1:重複なしで配列の行を連結する方法、別のテーブルを結合する

テーブル:

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使用1台あれば問題ありません

- SQLFiddle:http://sqlfiddle.com/#!1/4815e/20

私が行方不明です何が? JOINのためにこれを行うことは可能ですか?代わりに、ウィンドウ関数とpatitioningを使用しての

+3

私が与えることができれば5いい質問を、私はなります

This'dは、PostgreSQL(少なくとも9.1)はウィンドウ関数でDISTINCTをサポートしていないことを除いて、あまりにも窓関数アプローチで動作します。指定されたバージョン、テストデータ、期待される結果、試行されたクエリ。うまくいった。 –

+0

ありがとうございました – lana80

答えて

28

、クエリレベルの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句を使用して集計します。

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... 
+0

はい!!!!すばらしいです!!!!感謝万円!私は一日中努力を失い、あなたは1分で私に結果を与えた! :) – lana80

+0

Uが正しいです、私は別にしようとしましたが、私はそのエラーを得ていました! – lana80

+0

@ lana80あなたが必要とするものは、一日中同じ問題を見つめている時に、時には新鮮な目です。喜んで助けてください。 –