2012-09-11 13 views
27

Używam PostgreSQL 9.1 i potrzebuję pomocy w łączeniu wielu wierszy w jeden. Muszę to zrobić w 2 tabelach. Gdy używam dwóch funkcji array_agg(), otrzymuję w wyniku powielone wartości.PostgreSQL 9.1: jak łączyć wiersze w tablicy bez duplikatów, DOŁĄCZ do kolejnej tabeli

Stoły:

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 

Wynik:

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 

A co jest mi potrzebne:

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

Ten przykład w SQLFiddle: http://sqlfiddle.com/#!1/4815e/19

Nie ma problemu, jeśli zastosowanie jednej tabeli - SQLFiddle: http://sqlfiddle.com/#!1/4815e/20

Co mi brakuje? Czy można to zrobić z powodu JOIN?

+3

Jeśli mógłbym dać +5 dobre pytanie, chciałbym. Określona wersja, dane testowe, oczekiwane wyniki, próba zapytania. Ładnie wykonane. –

+0

Dziękuję bardzo – lana80

Odpowiedz

28

Zamiast używać funkcji okien i patitioning użyć GROUP zapytań poziom, i kruszywa o wyraźnej klauzuli:

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; 

Wynik:

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

Kluczem tutaj jest, że zamiast przy użyciu funkcji okien i patowania, używasz poziomu zapytania GROUP BY i agregujesz z klauzulą ​​DISTINCT.

This'd pracować z podejściem funkcja okna też, oprócz tego, że PostgreSQL (przynajmniej 9.1) nie obsługuje DISTINCT w funkcji okna:

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

TAK !!!! WSPANIAŁY!!!! Stukrotne dzięki! Straciłem cały dzień próbując, a dałeś mi wynik w ciągu jednej minuty! :) – lana80

+0

U mają rację, próbowałem odrębny ale dostałem ten błąd !!! – lana80

+0

@ lana80 Czasami potrzebujesz tylko świeżego zestawu oczu, kiedy cały dzień patrzysz na ten sam problem. Miło, że mogłem pomóc. –

Powiązane problemy