PostgreSQL 9.1: Cómo concatenar filas en una matriz sin duplicados, UNIRSE a otra tabla
Estoy usando PostgreSQL 9.1 y necesito ayuda para concatenar varias filas en una. Necesito hacer eso en 2 mesas. Cuando uso dos funciones array_agg()
veces obtengo valores duplicados en el resultado.
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 problema si se usa una tabla-SQLFiddle: http://sqlfiddle.com/#! 1 / 4815e/20
¿Qué me estoy perdiendo? ¿Es posible hacer esto, debido a UNIRSE?
1 answers
En lugar de usar funciones de ventana y patitioning, use un GRUPO a nivel de consulta y aggregate con una cláusula DISTINTA:
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 usar funciones de ventana y patitioning, se usa un nivel de consulta GROUP BY
y se agrega con una cláusula DISTINCT
.
Esto también funcionaría con el enfoque de función de ventana, excepto que PostgreSQL (al menos 9.1) no soporta DISTINCT
en funciones de 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...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-11 09:12:32