J'utilise PostgreSQL 9.1 et j'ai besoin d'aide pour concaténer plusieurs lignes en une. Je dois le faire dans 2 tableaux. Lorsque j'utilise deux fois les fonctions array_agg()
j'obtiens des valeurs dupliquées en résultat.
Les tables:
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
Résultat:
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
Et ce dont j'ai besoin c'est:
GRP_ID CABINETS ADDRESSES
11 cabs1,cabs2,cabs3,cabs4 NY,CA,
22 c1,c2 DC,LA
Cet exemple dans SQLFiddle: http://sqlfiddle.com/#!1/4815e/19
Il n'y a aucun problème si vous utilisez une table - SQLFiddle: http://sqlfiddle.com/#!1/4815e/2
Qu'est-ce que je rate? Est-il possible de le faire, grâce à JOIN?
Au lieu d'utiliser des fonctions de fenêtre et des applications, utilisez un GROUP BY de niveau requête et agrégez avec une clause 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;
Résultat:
grp_id | cabinets | addresses
--------+-------------------------+-----------
11 | cabs1,cabs2,cabs3,cabs4 | CA,NY
22 | c1,c2 | DC,LA
(2 rows)
La clé ici est qu'au lieu d'utiliser les fonctions de fenêtre et les requêtes, vous utilisez un niveau de requête GROUP BY
et agréger avec une clause DISTINCT
.
Cela fonctionnerait également avec l'approche de la fonction de fenêtre, sauf que PostgreSQL (9.1 au moins) ne prend pas en charge DISTINCT
dans les fonctions de fenêtre:
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...