IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes PostgreSQL Discussion :

Requête récursive : ordre des éléments par rapport au parent


Sujet :

Requêtes PostgreSQL

  1. #1
    Membre habitué
    Femme Profil pro
    Développeur Web
    Inscrit en
    Mai 2010
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2010
    Messages : 245
    Points : 164
    Points
    164
    Par défaut Requête récursive : ordre des éléments par rapport au parent
    Bonjour,

    J'ai la requete recursive suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    WITH recursive enfant(idEnfant,nomEnfant,parent,level) AS
    (
        SELECT d.id,d.nom,d.parent,0
        FROM domaine d where d.parent is null
      union ALL
        SELECT d.id,d.nom,d.parent,e.level+1
        FROM domaine d,enfant e
        where d.parent=e.idEnfant
    )
    SELECT idEnfant,nomEnfant,parent,level FROM enfant;
    Elle me retourne une série de domaine:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    idenfant	nomenfant	parent	 level
    DOM21455 	DOM1		NULL	          0
    DOM45123 	DOM2		DOM21455    1 
    DOM12421 	DOM3		DOM21455    1
    DOM95423 	DOM4		DOM21455    1
    DOM02354 	DOM5		DOM12421    2
    DOM75136 	DOM6		DOM45123    2
    DOM04452 	DOM7		DOM45123    2
    Je souhaiterai que la requete me retourne les domaines dans l'ordre suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    idenfant	nomenfant	parent	 level
    DOM21455 	DOM1		NULL	 0
    DOM45123 	DOM2		DOM21455 1 
    	DOM75136 	DOM6		DOM45123 2
    	DOM04452 	DOM7		DOM45123 2
    DOM12421 	DOM3		DOM21455 1
    	DOM02354 	DOM5	        DOM12421 2
    DOM95423 	DOM4		DOM21455 1
    Ma question est la suivante : est il possible de faire cela dans la requête ?

    Merci d'avance pour toutes infos.

    Chris

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 924
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 924
    Points : 51 726
    Points
    51 726
    Billets dans le blog
    6
    Par défaut
    C'est ce que l'on apelle un "sibling ordering".
    Ce n'est pas actuellement supporté par la norme SQL et donc pas par PG.
    J'ai publié une solution dans le forum SQL Server il y a un moment... Cherchez là, mais c'est assez complexe !

    A +

  3. #3
    Membre habitué
    Femme Profil pro
    Développeur Web
    Inscrit en
    Mai 2010
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2010
    Messages : 245
    Points : 164
    Points
    164
    Par défaut
    Bonjour,

    Merci pour votre réponse.
    J'y suis finalement arrivée.
    Voici le résultat avec le chemin pour chacun et le nombre d'enfant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    WITH RECURSIVE child AS
    					(
    			                SELECT d.id,d.nom,d.parent, 0 AS level, ARRAY[CAST(id AS VARCHAR)] AS path,x.noeud
    			                FROM domaine d,( select d.parent,count(*) as noeud from domaine d group by d.parent)x
    			                WHERE d.id='DOM87544915'
    			                and x.parent=d.id
    				        UNION ALL
    			                SELECT d.id,d.nom,d.parent,c.level + 1 AS level, path || CAST(d.id AS VARCHAR),x.noeud
    			                FROM child c JOIN domaine d ON d.parent = c.id left join ( select d.parent,count(*) as noeud from domaine d group by d.parent)x on x.parent=d.id
    					)
    					SELECT c.id,c.parent,c.nom,level,path,noeud
    					FROM child c
    					ORDER BY path

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    A mon sens c'est le nom plutôt que l'ID que tu veux mettre dans le tableau
    puisque sur ce morceau de résultat attendu:

    idenfant	nomenfant	parent	 level
    ..
    DOM75136 	DOM6		DOM45123 2
    DOM04452 	DOM7		DOM45123 2
    ...
    
    on voit qu'à un même niveau de hiérarchie, c'est trié par nomenfant croissant et non idenfant croissant.

    Mais à part ça la technique du tableau est effectivement celle qui va bien pour résoudre ce problème.

  5. #5
    Membre habitué
    Femme Profil pro
    Développeur Web
    Inscrit en
    Mai 2010
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2010
    Messages : 245
    Points : 164
    Points
    164
    Par défaut
    Dans l’idéal j'aimerai bien que cela soit rangé par nom mais lorsque je remplace id par nom
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    WITH RECURSIVE children AS
    					(
    			                SELECT d.id,d.nom as name,d.parent, 0 AS level, ARRAY[CAST(d.nom AS VARCHAR)] AS path,x.child
    			                FROM domaine d,( select d.parent,count(*) as child from domaine d group by d.parent)x
    			                WHERE d.id='DOM87544915'
    			                and x.parent=d.id
    				        UNION ALL
    			                SELECT d.id,d.nom as name,d.parent,c.level + 1 AS level, path || CAST(d.nom AS VARCHAR),x.child
    			                FROM children c JOIN domaine d ON d.parent = c.id left join ( select d.parent,count(*) as child from domaine d group by d.parent)x on x.parent=d.id
    					)
    					SELECT c.id,c.parent,c.name,level,path,child
    					FROM children c
    					ORDER BY path
    j'ai cette erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    ERREUR:  dans la requête récursive « children », la colonne 5 a le type character(1)[] dans le terme non
    récursif mais le type global bpchar[]
    LINE 3: ...  SELECT d.id,d.nom as name,d.parent, 0 AS level, ARRAY[CAST...
                                                                 ^
    HINT:  Convertit la sortie du terme non récursif dans le bon type.
    le champ nom est de type character varying(100)

  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Quels sont les types de données de domaine.nom et domaine.id ?

  7. #7
    Membre habitué
    Femme Profil pro
    Développeur Web
    Inscrit en
    Mai 2010
    Messages
    245
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2010
    Messages : 245
    Points : 164
    Points
    164
    Par défaut
    domaine.id : character(12)
    domaine.nom : character varying(100)

  8. #8
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Il faudrait faire le CAST vers le type TEXT au lieu de VARCHAR.

    D'ailleurs d'une manière générale TEXT est toujours préférable à VARCHAR sauf quand on veut impérativement limiter la taille de la donnée.

Discussions similaires

  1. [XSL][débutant]trié l'ordre des éléments d'un fichier xml
    Par pistache42 dans le forum XSL/XSLT/XPATH
    Réponses: 5
    Dernier message: 19/04/2006, 11h37
  2. [HTML]Positionner un élément par rapport à un autre
    Par Samanta dans le forum Balisage (X)HTML et validation W3C
    Réponses: 1
    Dernier message: 03/03/2006, 18h53
  3. [XSL] Ordre des éléments présentés
    Par Cupidon dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 23/01/2006, 14h58
  4. [C#] ordre des éléments dans un datagrid
    Par liliprog dans le forum ASP.NET
    Réponses: 3
    Dernier message: 19/09/2005, 17h31
  5. [débutant]Desactiver des champs par rapport a un select
    Par Pymm dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 16/02/2005, 17h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo