banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

Annonce

Rencontres QGIS 2025

L'appel à participation est ouvert jusqu'au 19 janvier 2025!

#1 Mon 23 February 2015 11:53

csv2
Participant occasionnel
Date d'inscription: 15 Sep 2014
Messages: 13

Equivalent de group_concat() dans PostGis

Bonjour
Dans un sujet consacré à la création d'index, Lsam avait donné une technique particulièrement efficace via sqlite/spatialite :

-après création d'une grille composée de "numero_carré", via le code

Code:

select "rues"."nom", group_concat("grille"."numero_carré")
from "rues" join "grille"
on intersects("rues"."geometry", "grille"."geometry")
group by 1

Je cherche à obtenir le même résultat mais dans postgresql (via pgadmin par exemple), du fait que mes bases sont dans postgresql/postgis.
Or la fonction group_concat semble ne pas exister en pgsql, et les autres fonctionner de manière différente.
Etant novice en la matière, j'ai beaucoup de difficultés à retrouver les fonctions qui me permettent de parvenir au même résultat.

Savez-vous si cela est possible ? Et si oui, avez-vous des pistes  à me proposer ?

Merci beaucoup !
Cyril

Hors ligne

 

#2 Mon 23 February 2015 16:26

MathieuB
Membre du bureau
Lieu: Montpellier
Date d'inscription: 18 Jan 2006
Messages: 1233
Site web

Re: Equivalent de group_concat() dans PostGis

Bonjour et bienvenue sur Georezo.

La liste des fonctions d’agrégation de PostgreSQL est décrite ici :

http://www.postgresql.org/docs/9.3/stat … egate.html

string_agg(expression, delimiter) devrait répondre à votre besoin.


Mathieu BOSSAERT
Association GeoRezo

Hors ligne

 

#3 Mon 23 February 2015 16:41

csv2
Participant occasionnel
Date d'inscription: 15 Sep 2014
Messages: 13

Re: Equivalent de group_concat() dans PostGis

Bonjour
et merci de votre réponse.
J'ai cherché du côté de string_agg, qui paraissait aller dans le bon sens.
Mais la logique étant différente et - me semble-t-il - plus complexe que celle de spatialite, je reste comme une poule devant un couteau. Il faut dire que je suis graphiste et analyste SIG, et que les BDD sont une terre nouvelle pour ma petite tête...
Je vais essayer de creuser... Si jamais une bonne âme a le temps et l'énergie de me donner une piste à suivre, ce serait très apprécié !
Merci encore, pour ce forum et l'aide apporté à la communauté !
Cyril

Hors ligne

 

#4 Tue 24 February 2015 09:24

MathieuB
Membre du bureau
Lieu: Montpellier
Date d'inscription: 18 Jan 2006
Messages: 1233
Site web

Re: Equivalent de group_concat() dans PostGis

Bonjour,

les deux fonctions sont les mêmes, sauf que group_concat ne nécessite pas de deuxième paramètres (le séparateur), qui est optionnel.

Ceci devrait fonctionner (notez que l'opératuer d'intersection est st_intersects ) :

Code:

select "rues"."nom", string_agg("grille"."numero_carré",',')
from "rues" join "grille"
on st_intersects("rues"."geometry", "grille"."geometry")
group by 1

string_agg("grille"."numero_carré",',') regroupera les valeurs de numero_carré de chaque nom de rue et les séparera par une virgule.


Mathieu BOSSAERT
Association GeoRezo

Hors ligne

 

#5 Tue 24 February 2015 17:51

csv2
Participant occasionnel
Date d'inscription: 15 Sep 2014
Messages: 13

Re: Equivalent de group_concat() dans PostGis

Ca alors ! Je tentais des opérations nettement plus complexes !
Il est vrai que le séparateur me posait problème ; mais je ne pensais pas possible de séparer table et colonne par un point dans postgis ! Du coup je cherchais à utiliser le FROM, etc.
Je vais tester votre solution !
Merci beaucoup !
Cyril

Hors ligne

 

#6 Tue 24 February 2015 17:59

csv2
Participant occasionnel
Date d'inscription: 15 Sep 2014
Messages: 13

Re: Equivalent de group_concat() dans PostGis

Je viens de tester : problème, je ne vois pas ce qui remplace la colonne geometry dans postgis !
Pour l'un j'ai bien une colonne wkb_geometry, mais rien pour l'autre !
Je vais creuser !

Hors ligne

 

#7 Wed 25 February 2015 09:23

Dof
Participant assidu
Lieu: Grenoble
Date d'inscription: 28 Oct 2009
Messages: 317
Site web

Re: Equivalent de group_concat() dans PostGis

Bonjour,
Je ne suis pas sur de comprendre le dernier message.
Pour ajouter la géométrie, il faut le mettre dans le select :

Code:

select "rues"."nom", string_agg("grille"."numero_carré",',') , wkb_geometry
from "rues" join "grille"
on st_intersects("rues"."geometry", "grille"."geometry")
group by 1

Edit : Vous pouvez aussi concaténer grâce au double pipe :

Code:

SELCT"rues"."nom", grille."numero_carré" || ',' as le_nouveau_nom, wkb_geometry
FROM"rues" 
JOIN "grille" ON st_intersects("rues"."geometry", "grille"."geometry")

Dernière modification par Dof (Wed 25 February 2015 09:29)

Hors ligne

 

#8 Wed 25 February 2015 11:07

csv2
Participant occasionnel
Date d'inscription: 15 Sep 2014
Messages: 13

Re: Equivalent de group_concat() dans PostGis

Bonjour
Et merci !
Ce forum est vraiment une perle !
En fait, les geometry qui me manquaient étaient celles qui suivaient la fonction st_intersects ; mais je les ai trouvé, pour chaque table.
Par contre, je vais tenter votre seconde solution, parce que, problème (encore !) : l'éditeur pgsql pgadmin3 ne reconnait pas la fonction string_agg ! Je ne comprends pas ! J'ai pourtant la version 9.3 de postgresql ! Mais il me donne le message "la fonction string_agg(integer, unknown) n'existe pas".
Merci de votre aide à tous deux !
Cyril

Hors ligne

 

#9 Wed 25 February 2015 11:26

csv2
Participant occasionnel
Date d'inscription: 15 Sep 2014
Messages: 13

Re: Equivalent de group_concat() dans PostGis

Suite : incompréhensible ! J'ai du éviter le string_agg, et passer par

Code:

select lines.name,
    array_to_string(ARRAY_AGG(test_carroyage.id), ';') As index
from "lines" 
    join "test_carroyage"
on st_intersects ("lines"."wkb_geometry", "test_carroyage"."geom")
group by 1

Pourtant ça c'est du pgsql 8, non ?
Bizarre bizarre...

Hors ligne

 

#10 Wed 25 February 2015 11:56

Dof
Participant assidu
Lieu: Grenoble
Date d'inscription: 28 Oct 2009
Messages: 317
Site web

Re: Equivalent de group_concat() dans PostGis

Les fonctions postgresql 8 fonctionnent sur une version 9 (pour la grande majorité tout du moins).
Je pense que votre problème vient du typage des données. La fonction string_agg, comme l'indique son nom, prend comme paramètres des chaines de caractères.
Vous devez donc convertir le 1er paramètre en string (vu le message, ça doit être un entier)
Pour cela :  on peut faire

test_carroyage.id::TEXT


Mais je viens de vérifier, il n'y a pas besoin de caster quand on utilise les || pour concaténer.

La conversion en array puis, en string est un peu tordu.

Si j'étais à votre place, je ferais au plus simple et au plus compréhensible :

Code:

SELECT lines.name,
    (test_carroyage.id || ';') As index
FROM"lines" 
JOIN "test_carroyage" ON st_intersects ("lines"."wkb_geometry", "test_carroyage"."geom")
GROUP BY 1

Par contre je ne comprends pas le GROUP BY 1

Dernière modification par Dof (Wed 25 February 2015 11:57)

Hors ligne

 

#11 Wed 25 February 2015 12:31

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1554

Re: Equivalent de group_concat() dans PostGis

Bonjour,

GROUP BY (comme ORDER BY) peut prendre des expressions ou des numéros de positions d'expressions:

"GROUP BY nom, id " peut ainsi etre écrit "GROUP BY 1, 2 " si nom et id sont les deux premieres colonnes du select.

Ca permet des raccourcis quand les expressions sont longues, et c'est source de belles erreurs dans les requetes complexes qd on modifie une expression du select.

Dans le cas de Cyril, le string_agg (ou autre fonction d'agrégat) est obligatoire car il veut grouper des identifiants par nom: la concaténation ne marche pas ici.
La version la plus simple est bien:

Code:

SELECT lines.name, string_agg(test_carroyage.id::text, ';') As index
FROM "lines" 
JOIN "test_carroyage" ON st_intersects ("lines"."wkb_geometry", "test_carroyage"."geom")
GROUP BY 1

Cyril, notez que Postgresql est le contraire d'incompréhensible wink

1. La fonction string_agg est décrite comme prenant un texte ou bytea en parametre:

Code:

db=# \df string_agg*
                                           Liste des fonctions
   Schéma   |        Nom         | Type de données du résultat | Type de données des paramètres |  Type
------------+--------------------+-----------------------------+--------------------------------+--------
 pg_catalog | string_agg         | bytea                       | bytea, bytea                   | agg
 pg_catalog | string_agg         | text                        | text, text                     | agg
 pg_catalog | string_agg_finalfn | text                        | internal                       | normal
 pg_catalog | string_agg_transfn | internal                    | internal, text, text           | normal

2. Le message de PG lors de l'utilisation dit exactement ca: la fonction string_agg(integer, unknown) n'existe pas:

L'avantage de ce message est qu'il indique la façon dont PG a utilisé la fonction string_agg: il l'a utilisée avec un integer et ne la connait pas avec ce type de parametre.

Nicolas

Hors ligne

 

#12 Wed 25 February 2015 13:33

csv2
Participant occasionnel
Date d'inscription: 15 Sep 2014
Messages: 13

Re: Equivalent de group_concat() dans PostGis

Aie, je suis repéré ! smile
C'est en effet incompréhensible POUR MOI  ! Mais il faut le dire, suite à vos explications très claires (dont je vous remercie vivement), ça devient limpide, à ma grande honte ! (Bon, enfin, limpide... me semble nécessaire de faire des progrès...)
En effet la concaténation ne marchait pas, j'ai essayé. Me reste donc à tester cette transformation en texte !
Je dois avouer que c'est passionnant, à partir du moment où de bonnes âmes se penchent sur le berceau du rigolo qui cherche à babiller !
Merci, merci !
Cyril

Hors ligne

 

#13 Wed 25 February 2015 14:09

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1554

Re: Equivalent de group_concat() dans PostGis

csv2 a écrit:

Aie, je suis repéré ! smile
C'est en effet incompréhensible POUR MOI  ! Mais il faut le dire, suite à vos explications très claires (dont je vous remercie vivement), ça devient limpide, à ma grande honte ! (Bon, enfin, limpide... me semble nécessaire de faire des progrès...)
En effet la concaténation ne marchait pas, j'ai essayé. Me reste donc à tester cette transformation en texte !
Je dois avouer que c'est passionnant, à partir du moment où de bonnes âmes se penchent sur le berceau du rigolo qui cherche à babiller !
Merci, merci !
Cyril


big_smile

(ouais, moi je fais le malin parce que ca fait 16 ans que je tripatouille des bd spatiales et ca commence juste a rentrer... yikes )

Hors ligne

 

#14 Wed 25 February 2015 14:20

csv2
Participant occasionnel
Date d'inscription: 15 Sep 2014
Messages: 13

Re: Equivalent de group_concat() dans PostGis

Dur... Je risque de sucrer les fraises avant d'y comprendre un minimum...

Hors ligne

 

#15 Wed 25 February 2015 16:00

csv2
Participant occasionnel
Date d'inscription: 15 Sep 2014
Messages: 13

Re: Equivalent de group_concat() dans PostGis

J'ai testé :

Code:

SELECT lines.name, string_agg(test_carroyage.id::text, ';') As index
FROM "lines" 
JOIN "test_carroyage" ON st_intersects ("lines"."wkb_geometry", "test_carroyage"."geom")
GROUP BY 1

Ca marche comme un seul homme.
C'est presque magique (non, je sais, juste logique !)

Hors ligne

 

Pied de page des forums

Powered by FluxBB