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

SQL Oracle Discussion :

Connect by prior : pourquoi ça marche pas


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut Connect by prior : pourquoi ça marche pas
    Décidément, Oracle a décidé me m'ennuyer jusqu'au bout ce matin...

    J'ai une table avec la structure suivante :

    TIE (CODSOC, TYPTIE, SIGTIE, TYPGRP, SIGGRP, ...)

    Souligné : Clé primaire
    Gras : Foreign key sur TIE (CODSOC, TYPTIE, SIGTIE)

    La table TIE contient donc des tiers.
    Ils peuvent être regroupés sous un autre tiers.

    Par exemple :
    Magasin 1 et Magasin 2 sont regroupés dans un même point de livraison, qui lui-même est regroupé dans une plateforme régionale, qui est elle-même regroupée dans une centrale d'achat nationale, qui elle-même est regroupée dans une enseigne.

    J'ai donc les données :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    CODSOC TYPTIE SIGTIE TYPGRP SIGGRP NOMTIE
       100 CLI    M1     PDL    P1     Magasin 1
       100 CLI    M2     PDL    P1     Magasin 2
       100 PDL    P1     REG    R1     PDL 1
       100 REG    R1     ACH    A1     Plateforme 1
       100 ACH    A1     ENS    E1     Centrale d'achat 1
       100 ENS    E1                   Enseigne 1
    Je souhaite retrouver l'ensemble des parents du client M1 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT level, typtie, sigtie
    FROM tie
    WHERE codsoc = 100
    CONNECT BY typtie = typgrp and sigtie = siggrp
    START WITH typtie = 'CLI' and sigtie = 'M1';
    Ca ne me retourne que la ligne M1... Pourquoi j'ai pas l'ensemble des parents ?

    J'ai déjà tenté d'intervertir l'ordre des champs dans le connect by, mais ça ne change rien...

    J'ai aussi tenté avec une CTE, mais j'ai pas trouvé la syntaxe pour faire une auto-jointure.

  2. #2
    Membre Expert
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Par défaut
    Il faut préciser les PRIOR :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT level, typtie, sigtie
    FROM tie
    WHERE codsoc = 100
    CONNECT BY PRIOR typgrp = typtie AND PRIOR siggrp = sigtie
    START WITH typtie = 'CLI' AND sigtie = 'M1';

  3. #3
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Merci, ça marche impec !

  4. #4
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Il faut aussi rajouter le codsoc dans le connect by sinon vous allez avoir des suprises.

  5. #5
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Waldar Voir le message
    Il faut aussi rajouter le codsoc dans le connect by sinon vous allez avoir des suprises.
    J'ai mis en filtre en dur sur CODSOC = 100 dans le WHERE, donc pas besoin ici.

    J'ai jamais compris d'ailleurs pourquoi il n'y avait pas un SOCGRP... Un groupe est forcément défini dans la même société que ses membres... Ca limite vachement la notion de référentiel supportée par le logiciel mais bon...

    Du coup, à partir du moment où le CODSOC est filtré, pas besoin de le spécifier dans le PRIOR.

  6. #6
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Le where dans les requêtes récursives s'applique après la récursion connect by.
    Avec de multiples branches, la requête va partir dans tous les codsoc pour ne filtrer qu'au résultat.
    Pour filtrer au départ, c'est à mettre dans le START WITH.

    En plus, vous zappez la récursion par la PK ce qui est dommage.

    J'ai recréé la table avec les données que vous avez fournies, regardez les plans d'exécution, c'est très net :
    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
    23
    24
    25
    26
    27
    28
    29
    30
        SELECT level, typtie, sigtie, nomtie
          FROM tie
         WHERE codsoc = 100
    CONNECT BY PRIOR typgrp = typtie
           AND PRIOR siggrp = sigtie
    START WITH typtie = 'CLI'
           AND sigtie = 'M1';
     
    ------------------------------------------------------------------------------------------------------------------------     
    | Id  | Operation                  | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |     
    ------------------------------------------------------------------------------------------------------------------------     
    |   0 | SELECT STATEMENT           |      |      1 |        |      8 |00:00:00.01 |      18 |       |       |          |     
    |*  1 |  FILTER                    |      |      1 |        |      8 |00:00:00.01 |      18 |       |       |          |     
    |*  2 |   CONNECT BY WITH FILTERING|      |      1 |        |      9 |00:00:00.01 |      18 |  2048 |  2048 | 2048  (0)|     
    |*  3 |    TABLE ACCESS FULL       | TIE  |      1 |      1 |      1 |00:00:00.01 |       3 |       |       |          |     
    |*  4 |    HASH JOIN               |      |      5 |        |      5 |00:00:00.01 |      15 |  1088K|  1088K|  727K (0)|     
    |   5 |     CONNECT BY PUMP        |      |      5 |        |      5 |00:00:00.01 |       0 |       |       |          |     
    |   6 |     TABLE ACCESS FULL      | TIE  |      5 |      1 |     35 |00:00:00.01 |      15 |       |       |          |     
    ------------------------------------------------------------------------------------------------------------------------     
     
     
    PLAN_TABLE_OUTPUT                                                                                                            
    -----------------------------------------------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):                                                                          
    ---------------------------------------------------                                                                          
     
       1 - filter("CODSOC"=100)                                                                                                  
       2 - access("TYPTIE"=PRIOR NULL AND "SIGTIE"=PRIOR NULL)                                                                   
       3 - filter(("TYPTIE"='CLI' AND "SIGTIE"='M1'))                                                                            
       4 - access("TYPTIE"=PRIOR NULL AND "SIGTIE"=PRIOR NULL)
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
        SELECT level, typtie, sigtie, nomtie
          FROM tie
         WHERE codsoc = 100
    CONNECT BY PRIOR typgrp = typtie
           AND PRIOR siggrp = sigtie
           AND PRIOR codsoc = codsoc
    START WITH typtie = 'CLI'
           AND sigtie = 'M1';
     
    ------------------------------------------------------------------------------------------------------------------------------         
    | Id  | Operation                      | Name   | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |         
    ------------------------------------------------------------------------------------------------------------------------------         
    |   0 | SELECT STATEMENT               |        |      1 |        |      5 |00:00:00.01 |      12 |       |       |          |         
    |*  1 |  FILTER                        |        |      1 |        |      5 |00:00:00.01 |      12 |       |       |          |         
    |*  2 |   CONNECT BY WITH FILTERING    |        |      1 |        |      5 |00:00:00.01 |      12 |  2048 |  2048 | 2048  (0)|         
    |*  3 |    TABLE ACCESS FULL           | TIE    |      1 |      1 |      1 |00:00:00.01 |       3 |       |       |          |         
    |   4 |    NESTED LOOPS                |        |      5 |        |      4 |00:00:00.01 |       9 |       |       |          |         
    |   5 |     CONNECT BY PUMP            |        |      5 |        |      5 |00:00:00.01 |       0 |       |       |          |         
    |   6 |     TABLE ACCESS BY INDEX ROWID| TIE    |      5 |      1 |      4 |00:00:00.01 |       9 |       |       |          |         
    |*  7 |      INDEX UNIQUE SCAN         | TIE_PK |      5 |      1 |      4 |00:00:00.01 |       5 |       |       |          |         
    ------------------------------------------------------------------------------------------------------------------------------         
     
    PLAN_TABLE_OUTPUT                                                                                                                      
    ---------------------------------------------------------------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):                                                                                    
    ---------------------------------------------------                                                                                    
     
       1 - filter("CODSOC"=100)                                                                                                            
       2 - access("TYPTIE"=PRIOR NULL AND "SIGTIE"=PRIOR NULL AND "CODSOC"=PRIOR NULL)                                                     
       3 - filter(("TYPTIE"='CLI' AND "SIGTIE"='M1'))                                                                                      
       7 - access("CODSOC"=PRIOR NULL AND "TYPTIE"=PRIOR NULL AND "SIGTIE"=PRIOR NULL)
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
        SELECT level, typtie, sigtie, nomtie
          FROM tie
    CONNECT BY PRIOR typgrp = typtie
           AND PRIOR siggrp = sigtie
           AND PRIOR codsoc = codsoc
    START WITH typtie = 'CLI'
           AND sigtie = 'M1'
           AND codsoc = 100;
     
    -----------------------------------------------------------------------------------------------------------------------------          
    | Id  | Operation                     | Name   | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |          
    -----------------------------------------------------------------------------------------------------------------------------          
    |   0 | SELECT STATEMENT              |        |      1 |        |      5 |00:00:00.01 |      11 |       |       |          |          
    |*  1 |  CONNECT BY WITH FILTERING    |        |      1 |        |      5 |00:00:00.01 |      11 |  2048 |  2048 | 2048  (0)|          
    |   2 |   TABLE ACCESS BY INDEX ROWID | TIE    |      1 |      1 |      1 |00:00:00.01 |       2 |       |       |          |          
    |*  3 |    INDEX UNIQUE SCAN          | TIE_PK |      1 |      1 |      1 |00:00:00.01 |       1 |       |       |          |          
    |   4 |   NESTED LOOPS                |        |      5 |        |      4 |00:00:00.01 |       9 |       |       |          |          
    |   5 |    CONNECT BY PUMP            |        |      5 |        |      5 |00:00:00.01 |       0 |       |       |          |          
    |   6 |    TABLE ACCESS BY INDEX ROWID| TIE    |      5 |      1 |      4 |00:00:00.01 |       9 |       |       |          |          
    |*  7 |     INDEX UNIQUE SCAN         | TIE_PK |      5 |      1 |      4 |00:00:00.01 |       5 |       |       |          |          
    -----------------------------------------------------------------------------------------------------------------------------          
     
    PLAN_TABLE_OUTPUT                                                                                                                      
    ---------------------------------------------------------------------------------------------------------------------------------------
     
    Predicate Information (identified by operation id):                                                                                    
    ---------------------------------------------------                                                                                    
     
       1 - access("TYPTIE"=PRIOR NULL AND "SIGTIE"=PRIOR NULL AND "CODSOC"=PRIOR NULL)                                                     
       3 - access("CODSOC"=100 AND "TYPTIE"='CLI' AND "SIGTIE"='M1')                                                                       
       7 - access("CODSOC"=PRIOR NULL AND "TYPTIE"=PRIOR NULL AND "SIGTIE"=PRIOR NULL)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MySQL] 2 boucles sur une requête, pourquoi ça marche pas?
    Par MisterMacPhisto dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 30/04/2007, 12h32
  2. Pourquoi ca marche pas :-(
    Par Flushovsky dans le forum Langage
    Réponses: 3
    Dernier message: 20/12/2005, 17h55
  3. Comprends pas pourquoi ca marche pas
    Par cellimo dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 08/11/2005, 22h10
  4. [OLE DB] pourquoi ca marche pas ??
    Par aurel89 dans le forum MFC
    Réponses: 3
    Dernier message: 09/09/2005, 17h23
  5. Accept : pourquoi ça marche pas ?
    Par doudblast dans le forum Linux
    Réponses: 16
    Dernier message: 08/03/2005, 11h48

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