2012-09-11 28 views
27

Tôi đang sử dụng PostgreSQL 9.1 và cần trợ giúp kết hợp nhiều hàng trong một. Tôi cần phải làm điều đó trong 2 bảng. Khi tôi sử dụng hai lần các hàm array_agg() tôi nhận được các giá trị trùng lặp trong kết quả.PostgreSQL 9.1: Cách nối các hàng trong mảng mà không trùng lặp, THAM GIA một bảng khác

Bàn:

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 

Kết quả:

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 

Và những gì tôi cần là:

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

Ví dụ này trong SQLFiddle: http://sqlfiddle.com/#!1/4815e/19

Không có vấn đề nếu sử dụng một bảng - SQLFiddle: http://sqlfiddle.com/#!1/4815e/20

tôi đang thiếu gì? Có thể làm điều này, bởi vì JOIN?

+3

Nếu tôi có thể cung cấp cho 5 câu hỏi hay, tôi sẽ. Phiên bản được chỉ định, dữ liệu thử nghiệm, kết quả mong đợi, truy vấn đã cố gắng. Thực hiện tốt. –

+0

Cảm ơn bạn rất nhiều – lana80

Trả lời

28

Thay vì sử dụng các chức năng cửa sổ và patitioning, sử dụng một truy vấn cấp GROUP BY và tổng hợp với một điều khoản riêng biệt:

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; 

Kết quả:

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

Mấu chốt ở đây là thay vì sử dụng các chức năng cửa sổ và sự kiểm tra, bạn sử dụng một mức truy vấn GROUP BY và tổng hợp với mệnh đề DISTINCT.

This'd làm việc với các cách tiếp cận chức năng cửa sổ cũng vậy, ngoại trừ PostgreSQL đó (9.1 ít nhất) không hỗ trợ DISTINCT trong các chức năng cửa sổ:

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

CÓ !!!! TUYỆT QUÁ!!!! Cảm ơn rất nhiều! Tôi đã mất cả ngày cố gắng, và bạn đã cho tôi kết quả trong một phút! :) – lana80

+0

U là đúng, tôi đã cố gắng khác biệt nhưng tôi đã nhận được lỗi đó !!! – lana80

+0

@ lana80 Đôi khi những gì bạn cần chỉ là một bộ mắt mới khi bạn nhìn chằm chằm vào cùng một vấn đề cả ngày. Vui mừng được giúp đỡ. –

Các vấn đề liên quan