Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 09/06/2011, 10h49   #1
Membre habitué
 
Inscription : janvier 2004
Messages : 507
Détails du profil
Informations forums :
Inscription : janvier 2004
Messages : 507
Points : 101
Points : 101
Par défaut Requête hiérarchique : incompréhension

Bonjour,

J'ai une table CLIENT avec ses données

ID IDCODE IDMGR MCODE ZONE
1 B 1 B 8
2 B 3 B 8
3 B 3 B 8
4 B 3 B 8
5 B 4 B 8

et ce que je souhaiterais
c'est quand je passe un client à la requête(pour une zone) je ramène tous ses manager(mgr)
je remonte la hiérarchie.

ex : si je prend le client 5 B alors je dois ramener son mgr c'est à dire 4 B.
Comme 4 B a pour mgr 3 B , je dois alors aussi ramener 3 B
et comme 3 B a pour manager 3 B je m'arrête la,
car quand le client = le manager alors c'est qu'on est au sommet de la chaine.

j'ai testé cette requête :

Code :
1
2
3
SELECT * FROM CLIENT WHERE zone = 8
start WITH ( ID= 5 AND IDCODE= B AND zone = 8)
connect BY nocycle IDMGR = prior ID AND MCODE = prior IDCODE
le souci est qu'elle ne me ramène
que
5 B 4 B
et s'arrête , elle ne remonte pas la hiérarchie jusqu'au sommet.
au lieu de

Citation:
5 B 4 B
4 B 3 B
3 B 3 B
Pourriez vous m’éclairer ?
j'ai sans douter oublié un truc dans la requête mais je ne vois pas

Merci
donny est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/06/2011, 11h25   #2
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 434
Points : 10 434
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Il faut déjà intervertir le PRIOR :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
WITH Client AS
(
SELECT 1 AS ID, 'B' AS IDCODE, 1 AS IDMGR, 'B' AS MCODE, 8 AS zone FROM dual union ALL
SELECT 2      , 'B'          , 3         , 'B'         , 8         FROM dual union ALL
SELECT 3      , 'B'          , 3         , 'B'         , 8         FROM dual union ALL
SELECT 4      , 'B'          , 3         , 'B'         , 8         FROM dual union ALL
SELECT 5      , 'B'          , 4         , 'B'         , 8         FROM dual
)
    SELECT ID, IDCODE, IDMGR, MCODE, ZONE, prior ID, prior IDMGR
      FROM CLIENT
start WITH ID = 5
       AND IDCODE = 'B'
       AND zone = 8
connect BY nocycle
           prior IDMGR = ID
       AND prior MCODE = IDCODE;
 
        ID I      IDMGR M       ZONE    PRIORID PRIORIDMGR
---------- - ---------- - ---------- ---------- ----------
         5 B          4 B          8                      
         4 B          3 B          8          5          4
Maintenant il manque la ligne 3.
Je pense qu'elle est filtrée à cause du NOCYCLE, comme elle boucle sur elle-même, le moteur la supprime du résultat.
Une petite astuce afin d'éviter la boucle est de gérer ce cas avec un nullif :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
    SELECT ID, IDCODE, IDMGR, MCODE, ZONE, prior ID, prior IDMGR
      FROM CLIENT
start WITH ID = 5
       AND IDCODE = 'B'
       AND zone = 8
connect BY prior nullif(IDMGR, ID) = ID
       AND prior IDCODE = MCODE;
 
        ID I      IDMGR M       ZONE    PRIORID PRIORIDMGR
---------- - ---------- - ---------- ---------- ----------
         5 B          4 B          8                      
         4 B          3 B          8          5          4
         3 B          3 B          8          4          3
À approfondir néanmoins.
__________________
Email : http://scr.im/waldar
Waldar est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/06/2011, 11h30   #3
Membre du Club
 
Inscription : décembre 2010
Messages : 190
Détails du profil
Informations forums :
Inscription : décembre 2010
Messages : 190
Points : 60
Points : 60
Bonjour,

Tu veux absolument une seule requête ou bien tu peux utiliser une boucle?
AbouZaid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/06/2011, 11h40   #4
Membre habitué
 
Inscription : janvier 2004
Messages : 507
Détails du profil
Informations forums :
Inscription : janvier 2004
Messages : 507
Points : 101
Points : 101
merci waldar
je vais tester et donc cela proviendrait du nocycle

sinon oui
je peux utiliser une boucle
mais comme j'ai vu que les requete hierarchique existait je voulais d abord voir si c etait possible avec
donny est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/06/2011, 12h43   #5
Membre habitué
 
Inscription : janvier 2004
Messages : 507
Détails du profil
Informations forums :
Inscription : janvier 2004
Messages : 507
Points : 101
Points : 101
j'ai l'impression que le deuxieme cas ne marche pas
celui avec le nullif
quand je le lances j 'ai ceci
Citation:
ORA-01436: CONNECT BY loop in user data
donny est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/06/2011, 13h25   #6
Membre habitué
 
Inscription : janvier 2004
Messages : 507
Détails du profil
Informations forums :
Inscription : janvier 2004
Messages : 507
Points : 101
Points : 101
je pense que c'est impossible de le faire sans passer par une boucle
ça a pas l'air vraiment au point le connect by
donny est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/06/2011, 14h04   #7
Membre émérite
 
Avatar de Drizzt [Drone38]
 
Homme
Inscription : mai 2004
Messages : 739
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Isère (Rhône Alpes)

Informations forums :
Inscription : mai 2004
Messages : 739
Points : 979
Points : 979
De mémoire, mais je ne suis pas un expert dans le domaine, une requete recursive ne pourrait-elle pas convenir ?

Tutoriel
__________________
Je ne réponds pas aux questions techniques par MP, le forum est là pour cela.

La crypto c'est comme les flambys, une fois que tu as trouvé la languette tu as juste à tirer pour tout faire tomber.

(\ _ /)
(='.'=)
Voici Lapinou. Aidez le à conquérir le monde
(")-(") en le reproduisant
Drizzt [Drone38] est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/06/2011, 14h10   #8
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 311
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
Localisation : France, Marne (Champagne Ardenne)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : octobre 2007
Messages : 3 311
Points : 5 808
Points : 5 808
Si mais il faut au moins Oracle 11g
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/06/2011, 14h33   #9
Membre habitué
 
Inscription : janvier 2004
Messages : 507
Détails du profil
Informations forums :
Inscription : janvier 2004
Messages : 507
Points : 101
Points : 101
je suis en 10g
c'est sans doute pour cela
par contre ce que je ne comprends pas
c'est quand j'utilise ma requête initiale
et que j'inverse le prior
comme ci-dessous :
Code :
1
2
3
SELECT * FROM CLIENT WHERE zone = 8
start WITH ( ID= 5 AND IDCODE= B AND zone = 8)
connect BY nocycle prior  IDMGR = ID AND prior  MCODE = IDCODE
elle me ramène énormément de lignes et des lignes qui n'ont rien avoir
???
donny est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/06/2011, 15h19   #10
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 434
Points : 10 434
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Citation:
Envoyé par mnitu Voir le message
Si mais il faut au moins Oracle 11g
Un petit complément : 11gR2 !
__________________
Email : http://scr.im/waldar
Waldar est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/06/2011, 15h41   #11
Membre habitué
 
Inscription : janvier 2004
Messages : 507
Détails du profil
Informations forums :
Inscription : janvier 2004
Messages : 507
Points : 101
Points : 101
pour que j essai de trouver une autre solution pourle faire,

je suis obliger de faire une fonction recursive en pl/sql ?
donny est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/06/2011, 15h56   #12
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 434
Points : 10 434
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Non pas nécessairement.
Sur le jeu de données fourni, une solution a été trouvée.

Vous dites que ça ne marche pas, mais sans nouveau jeu de données point de salut, je ne peux pas deviner ce qui ne fonctionne pas.

PS : connect by est une fonctionnalité qui existe depuis 1978, certes elle n'est pas parfaite (elle ne couvre pas tous les arbres récursifs contrairement aux CTE), mais on ne peut pas dire que ce n'est pas au point.
__________________
Email : http://scr.im/waldar
Waldar est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/06/2011, 12h24   #13
Expert Confirmé Sénior


 
Avatar de laurentschneider
 
Homme Laurent Schneider
Administrateur de base de données
Inscription : décembre 2005
Messages : 2 925
Détails du profil
Informations personnelles :
Nom : Homme Laurent Schneider
Localisation : Suisse

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

Informations forums :
Inscription : décembre 2005
Messages : 2 925
Points : 4 547
Points : 4 547
Citation:
Envoyé par Waldar Voir le message
PS : connect by est une fonctionnalité qui existe depuis 1978, certes elle n'est pas parfaite (elle ne couvre pas tous les arbres récursifs contrairement aux CTE), mais on ne peut pas dire que ce n'est pas au point.
Bon, NOCYCLE a été introduit en version 10 et est totalement décevant à mon gout... NOCYCLE n'est utile à mon sense que pour identifier les lignes qui cyclent mais c'est trop mauvais pour obtenir des résultats consistents

Voir http://laurentschneider.com/wordpres...rsive-cte.html inspiré de http://www.developpez.net/forums/d74...-hierarchique/
__________________
Mon blog : laurentschneider.com
Mon livre : Advanced Oracle SQL Programming
laurentschneider est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 15h48.


 
 
 
 
Partenaires

Hébergement Web