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 Tue 05 April 2016 18:25

Benoit91
Participant assidu
Date d'inscription: 2 Oct 2008
Messages: 263

postgres/postgis jointure sur champ à valeurs multiples

Bonjour

Je rencontre un problème de requête sql avec jointure.
Je m'explique:

Je dispose de 2 tables, 1 table parcelle (structurée avec le plugin cadastre de QGIS) et 1 table des logements sociaux.

Dans ma table des logements, j'ai un champ "refcada2" qui liste les parcelles sur laquelle ou lesquelles se situe la résidence des logements. J'ai donc ceci

logement          libelle_residence        refcada2
logement1              resid1                  AH0060
logement2              resid2                  AN0235,AN0236,AN0237
logement3              resid2                  AN0235,AN0236,AN0237


Je souhaite récupérer les parcelles (geom) qui localises les résidences (1 logement est dans une résidence qui se situe sur 1 ou plusieurs parcelles). J'ai tenté se type de requête (le row_number c'est pour un affichage dans qgis)

SELECT ROW_NUMBER() OVER() AS gid,
cada_parcelle.idu_id,
cada_parcelle.geom
FROM cadastre.cada_parcelle
INNER JOIN habitat.temp_rpls ON cada_parcelle.code_insee=insee
WHERE cada_parcelle.idu_temp IN (refcada2)
GROUP BY cada_parcelle.idu_id,cada_parcelle.geom


mais je ne récupère que les parcelles uniques dans le champ refcada2 soit ma resid1.

D'ailleurs je ne sais si c'est possible de pouvoir effectuer une jointure de ce type, sur un champ comprenant plusieurs valeurs.

Par avance, merci de votre aide.

Version de posgresql 9.4 et postgis 2.1

Dernière modification par Benoit91 (Tue 05 April 2016 18:27)

Hors ligne

 

#2 Tue 05 April 2016 18:53

VianneyD
Participant assidu
Date d'inscription: 30 May 2011
Messages: 153

Re: postgres/postgis jointure sur champ à valeurs multiples

Bonjour,

La solution doit se trouver du coté des regex.

Quelque chose de ce genre peut-être :

Code:

[...]
WHERE cada_parcelle.idu_temp IN 
  (SELECT regexp_split_to_table(refcada2,',') FROM habitat.temp_rpls)
[...]

Je n'ai pas testé donc sans garantie ^^


Vianney Dugrain

Hors ligne

 

#3 Wed 06 April 2016 11:09

Benoit91
Participant assidu
Date d'inscription: 2 Oct 2008
Messages: 263

Re: postgres/postgis jointure sur champ à valeurs multiples

Bonjour Vianney

Merci c'est exactement çà au niveau de la formule.
Je ne pratique pas assez postgres/postgis mais je vois que j'ai tout intérêt à m’intéresser au requêtes avec regexp.

La requête modifiée en conséquence

Code:

WITH parcelles_rpls AS (SELECT CONCAT (insee,'000',regexp_split_to_table(refcada2,',')) as idur FROM habitat.temp_rpls),
pcada AS (SELECT CONCAT ('91',cada_parcelle.idu_id) as idup, cada_parcelle.geom FROM cadastre.cada_parcelle)
SELECT ROW_NUMBER() OVER() AS gid,
pcada.idup,
pcada.geom
FROM pcada
JOIN parcelles_rpls ON idup=idur
GROUP BY idup,geom

Cordialement.

Dernière modification par Benoit91 (Wed 06 April 2016 12:18)

Hors ligne

 

#4 Wed 31 October 2018 11:45

BenB
Participant actif
Date d'inscription: 29 Dec 2015
Messages: 121

Re: postgres/postgis jointure sur champ à valeurs multiples

Bonjour,

je me permets de remonter ce post car je suis sur la même problématique,


j'ai deux tables, 1 table habitat (t_habitat) et 1 table de référence de l'INPN (habref_cb)


Pour récupérer  le libelle de l'habitat je dois faire une jointure sur un champs de la table t_habitat qui peut avoir plusieurs valeur séparés par une virgule :



t_habitat                                        habref_cb

gid     code_cb                                    code_cb                libelle
25        36.1                                    36.1                        Prés salés continentaux
26        87.24                                37.7                         Fourrés halophiles semi-désertiques
27        37.7                                    42.21                Dunes
28        36.1,42.21                                87.24                Prairies et landes des bancs de galets



Vue souhaitée


25        36.1                Prés salés continentaux
26        87.24            Prairies et landes des bancs de galets
27        37.7                Fourrés halophiles semi-désertiques
28        36.1,42.21            Prés salés continentaux, Dunes


Je n'arrive pas à intégrer l'expression suivante dans ma requête

SELECT regexp_split_to_table(code_cb,',') FROM pds_observatoire.t_habitat)

j'ai essayé en sous requête au niveau du LEFT JOIN en amont avec WITH.

il me manque aussi la deuxième partie de CONCATÉNATION des libelles

Je suis preneur de toute aide.

Merci !

Hors ligne

 

#5 Wed 31 October 2018 11:58

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

Re: postgres/postgis jointure sur champ à valeurs multiples

Bonjour,

Je vous conseillerais d'abord de changer la structure de la table t_habitat de sorte que les code_cb ne soient pas une liste de valeurs, mais des lignes séparées dans votre table, quitte à passer par une table de lien supplémentaire (lien n-m entre habitat et habref_cb).

Vous avez plusieurs possibilités pour traiter cette jointure, par ex:
• exploser code_cb en autant de ligne, puis faire une jointure sur habref_cb,
• ou construire un tableau de code_cb a partir de la liste texte de code_cb, et faire une jointure sur habref_cb en cherchahnt les code_cb contenus dans le tableau:

regex_split_to_array est utilisé dans la jointure pour construire un tableau de valeurs a partir d'une chaine texte.
element = any(array) renvoie vrai si element est présent dans le tableau: condition de jointure.

Code:

with t_habitat as (
  select * from (values (25, '36.1'),
    (26, '87.24'),
    (27, '37.7'),
    (28, '36.1,42.21')) as t(gid, code_cb)
), habref_cb as (
  select *
 from (values ('36.1', 'Prés salés continentaux'),
    ('37.7', 'Fourrés halophiles semi-désertiques'),
    ('42.21', 'Dunes'),
    ('87.24',  'Prairies et landes des bancs de galets')) as t(code_cb, libelle)
) select t.gid, t.code_cb, string_agg(h.libelle, ',') as code_cbs
from t_habitat t join habref_cb h on h.code_cb = any (regexp_split_to_array(t.code_cb, ','))
group by t.gid, t.code_cb
order by t.gid;

gid    code_cb        code_cbs
25    36.1          Prés salés continentaux
26    87.24          Prairies et landes des bancs de galets
27    37.7          Fourrés halophiles semi-désertiques
28    36.1,42.21    Prés salés continentaux,Dunes

Pour construire un texte qui est une liste de valeurs séparée par le caractère de votre choix, utilisez string_agg(text, char)

Nicolas

Dernière modification par Nicolas Ribot (Wed 31 October 2018 12:04)

Hors ligne

 

Pied de page des forums

Powered by FluxBB