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

Langage SQL Discussion :

Représentation intervallaire : Comment voir les feuilles et les noeuds fils direct ?


Sujet :

Langage SQL

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2010
    Messages : 4
    Points : 3
    Points
    3
    Par défaut Représentation intervallaire : Comment voir les feuilles et les noeuds fils direct ?
    Bonjour !

    J'ai cree un arbre comme explique sur cet article :
    http://sqlpro.developpez.com/cours/arborescence/



    Ca fonctionne à merveille. Mais j'ai une requête qui me semble impossible à faire...

    Je veux récupérer les noeuds et les feuilles "fils / filles" directements liées au noeud "Terrestre" (père), càd :
    • Moto
    • Camion
    • Voiture
    • Vélo

    mais PAS Trail et Side-car (feuilles filles de "Moto").

    Est-ce réalisable avec la representation intervallaire ?

    Merci pour votre aide !

  2. #2
    Membre éprouvé Avatar de Oishiiii
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2009
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Août 2009
    Messages : 508
    Points : 1 107
    Points
    1 107
    Par défaut
    Bonjour,

    C'est possible, mais pour cela il faut compter les niveaux de chaque éléments de la branche.

    Essayez ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    SELECT 	noeud.nfm_lib,
    		(COUNT(parent.nfm_lib) - (td.niveau + 1)) AS niveau
    FROM new_famille AS noeud
    	JOIN new_famille AS parent
    		ON noeud.bg BETWEEN parent.bg AND parent.bd
    	JOIN new_famille AS enfant
    		ON noeud.bg BETWEEN enfant.bg AND enfant.bd
    	JOIN (
    		SELECT noeud.nfm_lib, (COUNT(parent.nfm_lib) - 1) AS niveau
    		FROM new_famille AS noeud, 
    			JOIN new_famille AS parent
    				ON noeud.bg BETWEEN parent.bg AND parent.bd
    		WHERE noeud.nfm_lib = 'Terrestre'
    		GROUP BY noeud.nfm_lib
    	) AS td
    		ON td.nfm_lib = enfant.nfm_lib
    GROUP BY noeud.nfm_lib
    HAVING niveau = 1

  3. #3
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 849
    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 849
    Points : 52 975
    Points
    52 975
    Billets dans le blog
    6
    Par défaut
    Oulala, c'est lourd !!!!

    Citation Envoyé par Oishiiii Voir le message
    Bonjour,

    C'est possible, mais pour cela il faut compter les niveaux de chaque éléments de la branche.

    Essayez ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    SELECT 	noeud.nfm_lib,
    		(COUNT(parent.nfm_lib) - (td.niveau + 1)) AS niveau
    FROM new_famille AS noeud
    	JOIN new_famille AS parent
    		ON noeud.bg BETWEEN parent.bg AND parent.bd
    	JOIN new_famille AS enfant
    		ON noeud.bg BETWEEN enfant.bg AND enfant.bd
    	JOIN (
    		SELECT noeud.nfm_lib, (COUNT(parent.nfm_lib) - 1) AS niveau
    		FROM new_famille AS noeud, 
    			JOIN new_famille AS parent
    				ON noeud.bg BETWEEN parent.bg AND parent.bd
    		WHERE noeud.nfm_lib = 'Terrestre'
    		GROUP BY noeud.nfm_lib
    	) AS td
    		ON td.nfm_lib = enfant.nfm_lib
    GROUP BY noeud.nfm_lib
    HAVING niveau = 1
    Le mieux est de stocker le niveau avec les bornes gauches et droite en mode intervallaire, comme je le suggère dans mon article http://sqlpro.developpez.com/cours/arborescence/#L2.14

    Dès lors avec la colonne NFM_NV (niveau), la requête s'écrit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT Tout.*
    FROM   NEW_FAMILLE AS Tout
           INNER JOIN NEW_FAMILLE AS Tin
                 ON     Tout.NFM_BG > Tin.NFM_BG
                    AND Tout.NFM_BD < Tin.NFM_BD
                    AND Tout.NFM_NV = Tin.NFM_NV + 1 --> descendant de niveau 1
    WHERE  Tin.NFM_LIB = 'Terrestre'  --> noeud de référence
    A +

  4. #4
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 091
    Points : 31 510
    Points
    31 510
    Billets dans le blog
    16
    Par défaut
    Bonsoir,


    Une variante.

    Si votre SGBD sait traiter de la récursivité, une technique générale peut consister à calculer la fermeture transitive d’une nomenclature, puis l’exploiter pour les cas particuliers. Voyez par exemple la discussion avec antonomas : Représentation d'arbres entremêlés.

    Remplaçons-y ENTREPRISE par MOYEN (sous-entendu de locomotion) et ACTIONNAIRE par NOMENCLATURE.

    Création des tables :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    CREATE TABLE MOYEN
    (
            MoyId    Char(6)      NOT NULL
          , MoyNom   Varchar(32)  NOT NULL
        , CONSTRAINT MOYEN_PK PRIMARY KEY (MoyId)
    ) ;
    CREATE TABLE NOMENCLATURE
    (
            EnfantId    Char(6)      NOT NULL
          , ParentId    Char(6)      NOT NULL
        , CONSTRAINT NOMENCL_PK PRIMARY KEY (EnfantId, ParentId)
        , CONSTRAINT NOMENCL_FK1 FOREIGN KEY (EnfantId) REFERENCES MOYEN (MoyId)
        , CONSTRAINT NOMENCL_FK2 FOREIGN KEY (ParentId) REFERENCES MOYEN (MoyId)
        , CONSTRAINT NOMENCL_CHK1 CHECK (EnfantId <> ParentId)
    ) ;
    Alimentation de la table MOYEN :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    INSERT INTO MOYEN VALUES ('e01', 'transport') ;
    INSERT INTO MOYEN VALUES ('e02', 'marin') ;
    INSERT INTO MOYEN VALUES ('e03', 'terrestre') ;
    INSERT INTO MOYEN VALUES ('e04', 'aérien') ;
    INSERT INTO MOYEN VALUES ('e05', 'voilier') ;
    INSERT INTO MOYEN VALUES ('e06', 'paquebot') ;
    INSERT INTO MOYEN VALUES ('e07', 'planche à voile') ;
    INSERT INTO MOYEN VALUES ('e08', 'moto') ;
    INSERT INTO MOYEN VALUES ('e09', 'camion') ;
    INSERT INTO MOYEN VALUES ('e10', 'voiture') ;
    INSERT INTO MOYEN VALUES ('e11', 'vélo') ;
    INSERT INTO MOYEN VALUES ('e12', 'avion') ;
    INSERT INTO MOYEN VALUES ('e13', 'uml') ;
    INSERT INTO MOYEN VALUES ('e14', 'fusée') ;
    INSERT INTO MOYEN VALUES ('e15', 'hélicoptère') ;
    INSERT INTO MOYEN VALUES ('e16', 'parachute') ;
    INSERT INTO MOYEN VALUES ('e17', 'planeur') ;
    INSERT INTO MOYEN VALUES ('e18', 'trail') ;
    INSERT INTO MOYEN VALUES ('e19', 'side-car') ;
    INSERT INTO MOYEN VALUES ('e20', 'civil') ;
    INSERT INTO MOYEN VALUES ('e21', 'tourisme') ;
    INSERT INTO MOYEN VALUES ('e22', 'militaire') ;
    Alimentation de la table NOMENCLATURE :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    INSERT INTO NOMENCLATURE VALUES ('e02', 'e01') ;
    INSERT INTO NOMENCLATURE VALUES ('e03', 'e01') ;
    INSERT INTO NOMENCLATURE VALUES ('e04', 'e01') ;
    INSERT INTO NOMENCLATURE VALUES ('e05', 'e02') ;
    INSERT INTO NOMENCLATURE VALUES ('e06', 'e02') ;
    INSERT INTO NOMENCLATURE VALUES ('e07', 'e02') ;
    INSERT INTO NOMENCLATURE VALUES ('e08', 'e03') ;
    INSERT INTO NOMENCLATURE VALUES ('e09', 'e03') ;
    INSERT INTO NOMENCLATURE VALUES ('e10', 'e03') ;
    INSERT INTO NOMENCLATURE VALUES ('e11', 'e03') ;
    INSERT INTO NOMENCLATURE VALUES ('e12', 'e04') ;
    INSERT INTO NOMENCLATURE VALUES ('e13', 'e04') ;
    INSERT INTO NOMENCLATURE VALUES ('e14', 'e04') ;
    INSERT INTO NOMENCLATURE VALUES ('e15', 'e04') ;
    INSERT INTO NOMENCLATURE VALUES ('e16', 'e04') ;
    INSERT INTO NOMENCLATURE VALUES ('e17', 'e04') ;
    INSERT INTO NOMENCLATURE VALUES ('e18', 'e08') ;
    INSERT INTO NOMENCLATURE VALUES ('e19', 'e08') ;
    INSERT INTO NOMENCLATURE VALUES ('e20', 'e12') ;
    INSERT INTO NOMENCLATURE VALUES ('e21', 'e12') ;
    INSERT INTO NOMENCLATURE VALUES ('e22', 'e12') ;
    Création d’une vue récursive avec laquelle on amorce la pompe avec la racine 'e01' (transport) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    CREATE VIEW DESCENDANCE (Parent, Enfant)
    AS
    WITH DESCENDANCE (ParentId, EnfantId) AS
    (
     (
      SELECT   ParentId, EnfantId
      FROM     NOMENCLATURE
      WHERE    ParentId = 'e01'
     )
    UNION ALL
     (SELECT   x.ParentId, x.EnfantId
      FROM     NOMENCLATURE AS x JOIN DESCENDANCE AS y
                 ON y.EnfantId = x.ParentId
     )
    )
    SELECT DISTINCT z.MoyNom AS Parent, y.MoyNom AS Enfant 
    FROM   DESCENDANCE AS x 
             JOIN MOYEN AS y ON x.EnfantId = y.MoyId
             JOIN MOYEN AS z ON x.ParentId = z.MoyId ;
    Pour connaître les moyens directement rattachés au moyen 'terrestre' et eux seuls :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT DISTINCT *
    FROM   DESCENDANCE
    WHERE Parent = 'terrestre' ;

Discussions similaires

  1. Réponses: 4
    Dernier message: 04/03/2014, 11h58
  2. Réponses: 0
    Dernier message: 08/12/2008, 14h50
  3. Réponses: 2
    Dernier message: 22/08/2007, 12h46
  4. Réponses: 3
    Dernier message: 22/05/2006, 17h00

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