2012-09-11 1188 views
27

Estoy usando PostgreSQL 9.1 y necesito ayuda para concatenar varias filas en una. Necesito hacer eso en 2 tablas. Cuando uso dos veces las funciones array_agg() obtengo valores duplicados en el resultado.PostgreSQL 9.1: Cómo concatenar filas en la matriz sin duplicados, UNIRSE a otra tabla

Tablas:

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 

Resultado:

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 

Y lo que necesito es:

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

Este ejemplo en SQLFiddle: http://sqlfiddle.com/#!1/4815e/19

No hay ningún problema si el uso de una tabla - SQLFiddle: http://sqlfiddle.com/#!1/4815e/20

¿Qué me falta? ¿Es posible hacer esto, debido a JOIN?

+3

Si pudiera dar 5 buena pregunta, lo haría. Versión especificada, datos de prueba, resultados esperados, intento de consulta. Bien hecho. –

+0

Muchas gracias – lana80

Respuesta

28

En lugar de utilizar las funciones de ventana y patitioning, utilizar un grupo de nivel de consulta BY y agregada con una cláusula 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; 

Resultado:

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

La clave aquí es que en lugar de utilizar funciones de ventana y planificación, utiliza un nivel de consulta GROUP BY y agrega una cláusula DISTINCT.

This'd trabajar con el enfoque de la función de ventana también, excepto que PostgreSQL (9.1 por lo menos) no es compatible con DISTINCT en funciones de la ventana:

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

¡¡SÍ !!!! ¡¡¡¡ESTUPENDO!!!! ¡Un millón de gracias! ¡Perdí todo un día intentando y me diste resultado en un minuto! :) – lana80

+0

U tienen razón, lo intenté distinto pero estaba recibiendo ese error !!! – lana80

+0

@ lana80 A veces lo que necesita es solo un par de ojos frescos cuando ha estado mirando el mismo problema todo el día. Encantado de ayudar. –

Cuestiones relacionadas