Nous utilisons des cookies pour vous garantir la meilleure expérience sur notre site. Si vous continuez à utiliser ce dernier, nous considèrerons que vous acceptez l'utilisation des cookies. J'ai compris ! ou En savoir plus !.
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Ă© ?

#1 Wed 07 August 2013 15:38

melimelo
Participant actif
Lieu: Nantes
Date d'inscription: 19 May 2006
Messages: 87
Site web

PostgreSQL 8.4 : requĂȘte sur liste de valeurs

Bonjour,

je souhaiterai un peu d'aide, je bloque sur la rĂ©daction d'une requĂȘte. Non initiĂ©e, il me manque certainement des Ă©lĂ©ments SQL...

Je dispose de deux tables : les espaces naturels et les réglementations des activités associées.

Table "espaces naturels" (ENP)                                           Table "reglementation_activites" (RA)
--------------------------------------                                       -------------------------------------------
ENP.code (identifiant)                                                         RA.code_enp
ENP.nom                                                                           RA.code_activitĂ©s
ENP.dĂ©signation                                                                 RA. frĂ©quence_rĂ©glementation (permanente/temporaire)
ENP.date_crĂ©ation                                                              RA.caractĂšre_rĂ©glementation (charte/autorisĂ©/interdite)
etc....                                                                                etc...

Je m’intĂ©resse Ă  une liste d'activitĂ©s en particulier, soient les activitĂ©s 5,6,7,9,11,23,25,26,30.

Je souhaiterai avoir une liste des espaces naturels oĂč :
- une des activités listées est présente (à minima une seule)
- toutes les activités listées sont présentes

Pour la premiĂšre je suis partie sur cette requĂȘte :
select distinct ENP.code, ENP.nom, ENP.désignation
from espaces_naturels as ENP
left join regulations_activities as RA ON ENP.code = RA.code_enp
where activities_list_activities_id IN (5,6,7,9,11,23,25,26,30)

Je n'arrive pas à lister les espaces protégés qui listent touts les activités ciblées.

J'attends vos conseils, idées avec impatience.

Merci,
Mélanie

Hors ligne

 

#2 Wed 07 August 2013 17:10

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

Re: PostgreSQL 8.4 : requĂȘte sur liste de valeurs

Bonjour,

Une piste possible pour résoudre cela:

Créer une liste ordonnée de toutes les activités pour un espace naturel et comparer cette liste avec la liste attendue.
Au final, ne choisir que les espaces naturels qui ont une liste complete d'activité.

Avec Postgresql, les ARRAYS permettent de faire ça de façon plutÎt efficace:


Code:

-- premiere requete donnant la liste ordonnée des activités pour tous les Espaces naturels
with ordered_act as (
    select * from regulations_activities order by code_enp, activities_list_activities_id
), 
-- deuxieme requete qui agrÚge dans un tableau toutes les activités pour chaque espace naturel.
-- le tableau est ordonné grace a la requete précédente.
agg_act as (
    select code_enp, array_agg(o.activities_list_activities_id) as arr_act
    from ordered_act o
    group by code_enp
) 
-- enfin, selection de tous les espaces naturels qui ont une liste complete d'activités
select * from espaces_naturels e left join agg_act a on (e.code = a.code_enp)
where a.arr_act = '{5,6,7,9,11,23,25,26,30}';

La syntaxe '{5,6,7,9,11,23,25,26,30}' permet de créer un tableau d'entiers.

Nicolas

Hors ligne

 

#3 Thu 08 August 2013 09:59

melimelo
Participant actif
Lieu: Nantes
Date d'inscription: 19 May 2006
Messages: 87
Site web

Re: PostgreSQL 8.4 : requĂȘte sur liste de valeurs

Merci Nicolas pour cette proposition,

La requĂȘte tourne mais ne renvoie aucun rĂ©sultat alors que je sais qu'au moins un ENP liste toutes ces activitĂ©s....

Hors ligne

 

#4 Thu 08 August 2013 10:19

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

Re: PostgreSQL 8.4 : requĂȘte sur liste de valeurs

Se peut-il qu'il y ait plusieurs activitĂ©s identiques pour un meme ENP ? Si oui, il faut modifier la requĂȘte pour filtre les doublons avant de construire la liste des activitĂ©s pour un ENP. (sans ce filtre, la liste peut ressembler Ă  {2,2,5,7,7,9,11} et ne pas ĂȘtre egale au critĂšre de filtre).

Pouvez-vous partager vos données ou une partie de celles-ci ?

Nicolas

Hors ligne

 

#5 Thu 08 August 2013 16:12

melimelo
Participant actif
Lieu: Nantes
Date d'inscription: 19 May 2006
Messages: 87
Site web

Re: PostgreSQL 8.4 : requĂȘte sur liste de valeurs

Une mĂȘme activitĂ© ne peut ĂȘtre listĂ©e qu'une seule fois dans chaque espace naturel.

Je joins ici un extrait de la donnée espace naturel (format Shape) et de la table "regulations_activities".

Le lien entre les deux tables se fait via le champ gid pour le Shape et le champ wdpa_gid pour la table.

Si je cherche les espaces naturels ayant les activités (33 et 34 et 35 et 36 et 37 et 38), je devrais trouver à minima le gid = 43.

Merci pour votre aide !

Dernière modification par melimelo (Thu 08 August 2013 16:25)


Fichier(s) joint(s) :
Pour accéder aux fichiers vous devez vous inscrire.

Hors ligne

 

#6 Thu 08 August 2013 17:07

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

Re: PostgreSQL 8.4 : requĂȘte sur liste de valeurs

Ok: ma requete faisait une comparaison stricte entre les activitĂ©s d'un ENP et la valeur Ă  tester. Il faut utiliser l'opĂ©rateur Contains "@>" (http://www.postgresql.org/docs/8.4/inte … array.html) entre les tableaux pour chercher tous les ENP qui contiennent toutes les activitĂ©s voulues:

La table des activités est ra, celle des espaces naturels: enp
(S'il ne s'agit que de récupérer l'identifiant des ENP, le left join dans la requete ci-apres est inutile)

Code:

with o as (
    select * from ra order by wdpa_gid, activities
), agg as (
    select wdpa_gid, array_agg(o.activities) as val
    from o
    group by wdpa_gid
) select e.__gid, val from enp e left join agg a on (e.__gid = a.wdpa_gid)
where a.val @> '{33,34,35,36,37,38}'

Cela donne, avec le jeu de résultats transmis:

Code:

43    {4,8,11,14,15,33,34,35,36,37,38,50}
204    {33,34,35,36,37,38,44,45,50}
208    {12,15,16,32,33,34,35,36,37,38,44,47,48,50}
210    {15,16,17,18,32,33,34,35,36,37,38,40,42,43,44,45,47,50}
212    {12,16,33,34,35,36,37,38,44,45,50}
214    {6,12,16,33,34,35,36,37,38,44,45,50}
216    {12,33,34,35,36,37,38,45,50}
226    {3,4,5,10,12,16,17,32,33,34,35,36,37,38,44,47,50}

Nicolas

Hors ligne

 

#7 Thu 08 August 2013 17:25

melimelo
Participant actif
Lieu: Nantes
Date d'inscription: 19 May 2006
Messages: 87
Site web

Re: PostgreSQL 8.4 : requĂȘte sur liste de valeurs

Cela fonctionne !!!!!

J'ai une question subsidiaire :
si je voulais sélectionner uniquement les espaces naturels avec seulement les activités "33,34,35,36,37,38", je devrais écrire :
where a.val = '{33,34,35,36,37,38}' ?


La requĂȘte pour lister les espaces naturels qui ont au moins une des activitĂ©s listĂ©es vous parait-elle correcte ?

Code:

select distinct ENP.code, ENP.nom, ENP.désignation
from espaces_naturels as ENP
left join regulations_activities as RA ON ENP.code = RA.code_enp
where activities_list_activities_id IN (5,6,7,9,11,23,25,26,30)

Ca avance, merci !!

Dernière modification par melimelo (Thu 08 August 2013 17:34)

Hors ligne

 

#8 Thu 08 August 2013 18:06

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

Re: PostgreSQL 8.4 : requĂȘte sur liste de valeurs

Oui tout a fait "=" entre les tableaux fait une comparaison stricte.

Oui la requete pour au moins une activité est bien: left join, opérateur "IN".

Nicolas

Hors ligne

 

#9 Thu 08 August 2013 19:03

melimelo
Participant actif
Lieu: Nantes
Date d'inscription: 19 May 2006
Messages: 87
Site web

Re: PostgreSQL 8.4 : requĂȘte sur liste de valeurs

Parfait !

Merci pour ces précisions,
Mélanie

Hors ligne

 

Pied de page des forums

Copyright Association GeoRezo