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 :

requete hierarchique + join condition


Sujet :

SQL Oracle

  1. #1
    Membre actif Avatar de speedy_g
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    213
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2007
    Messages : 213
    Points : 242
    Points
    242
    Par défaut requete hierarchique + join condition
    Bonjour à tous

    J'ai un problème d'écriture d'une requête.

    J'ai un ensemble d'échantillons localisés par une table comprenant une hiérarchie.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Table 1 = Samples(ID,ID_TBL2) 
    Table 2 = Localizations(ID,ID_PARENT,DESCRIPTION)
     
    ID_TBL2 correspond au lien entre Table 1 et Table 2 ( cléf étrangère)
    ID_PARENT est le lien de hierarchie dans la table 2
    J'aimerais avoir une requete qui m'affiche pour chaque échantillon, l'ensemble de ses localisations.

    i.e
    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
     
    Table 1                          Table 2 
    -------                          -------
    ID  ID_TBL2                      ID ID_PARENT DESCRIPTION
    1   5                            1  0          dec1             
    2   1                            2  1          dec2 
                                     5  2          dec3 
                                     0  null       root
    => requete 
       -------
    (Table 1)ID       (Table 2) ID      (Table 2) Description
    1                    5               dec3
    1                    2               dec2
    1                    1               dec1
    1                    0               root
    2                    1               dec1
    2                    0               root
    J'ai essayé de faire une jointure entre les deux tables puis de créer un connect by

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    select a.ID, b.ID 
    from (Table 1) a,
         (Table 2) b
    where a.ID = b.ID
    connect by b.ID = prior b.ID_PARENT
    mais ca ne fonctionne pas du tout comme je voudrais ( probablement car la condition de jointure est d'abord effectuée ).

    Auriez vous des idées ?

    Merci d'avance

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Ici j'ai d'abord parcouru la hierarchie puis effectué la jointure à postériori :
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    WITH TABLE1 AS
    (
    select 1 as ID, 5 as ID_TBL2 from dual union all                            
    select 2      , 1            from dual
    ),
         TABLE2 AS
    (
    select 1 as ID, 0 AS ID_P, 'dec1' AS txt  from dual union all
    select 2      , 1        , 'dec2'         from dual union all
    select 5      , 2        , 'dec3'         from dual union all
    select 0      , NULL     , 'root'         from dual
    ),
         HIER AS
    (
    select
        connect_by_root id as id_init,
        id,
        txt
    from
        TABLE2
    start with
        ID in (select ID_TBL2 from TABLE1)
    connect BY
        ID = prior ID_P
    )
    select
        T1.ID,
        HI.ID,
        HI.txt
    from
        TABLE1 T1
        inner join HIER HI
          on HI.id_init = T1.ID_TBL2
    order by
        T1.ID asc,
        HI.ID desc;
     
    ID	ID_1	TXT
    1	5	dec3
    1	2	dec2
    1	1	dec1
    1	0	root
    2	1	dec1
    2	0	root

  3. #3
    Expert confirmé
    Avatar de laurentschneider
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2005
    Messages
    2 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 2 944
    Points : 4 926
    Points
    4 926
    Par défaut
    un tout petit peu différement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    select connect_by_root t1_id,id, txt 
    from (
      select (select t1.id from t1 where t1.id_tbl2=t2.id) t1_id, t2.* 
      from t2 
    ) 
    connect by id = prior id_p
    start with t1_id is not null;

  4. #4
    Membre averti Avatar de xdescamp
    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 300
    Points : 442
    Points
    442
    Par défaut
    Citation Envoyé par laurentschneider Voir le message
    un tout petit peu différement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    select connect_by_root t1_id,id, txt 
    from (
      select (select t1.id from t1 where t1.id_tbl2=t2.id) t1_id, t2.* 
      from t2 
    ) 
    connect by id = prior id_p
    start with t1_id is not null;
    Sauf erreur, ta requête ne fonctionne que s'il n'y a qu'un seul enregistrement dans t1 qui référence t2.
    J'étais plutôt parti sur le même principe, mais avec une jointure externe:
    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
    with table_1 as (select 1 id, 5 id_tbl2 from dual union all
                     select 2 id, 1 id_tbl2 from dual),
         table_2 as (select 1 id, 0 id_parent, 'dec1' description from dual union all
                     select 2 id, 1 id_parent, 'dec2' description from dual union all
                     select 5 id, 2 id_parent, 'dec3' description from dual union all
                     select 0 id, null id_parent, 'root' description from dual)
    select connect_by_root id_1, id_2, description
    from (select table_1.id id_1, table_2.id id_2, table_2.id_parent id_parent_2, table_2.description
          from table_1,
               table_2
          where table_2.id = table_1.id_tbl2(+))
    Connect by prior id_parent_2 = id_2
    start with id_1 is not null;
     
    CONNECT_BY_ROOTID_1       ID_2 DESC
    ------------------- ---------- ----
                      2          1 dec1
                      2          0 root
                      1          5 dec3
                      1          2 dec2
                      1          1 dec1
                      1          0 root

  5. #5
    Membre actif Avatar de speedy_g
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    213
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2007
    Messages : 213
    Points : 242
    Points
    242
    Par défaut
    Merci beaucoup pour vos réponses,

    Je vais les essayer toutes, et essayer de comprendre aussi .... .
    (Je n'en suis qu'à mes débuts en sql.)


    Johan

  6. #6
    Expert confirmé
    Avatar de laurentschneider
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Décembre 2005
    Messages
    2 944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

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

    Informations forums :
    Inscription : Décembre 2005
    Messages : 2 944
    Points : 4 926
    Points
    4 926
    Par défaut
    Citation Envoyé par xdescamp Voir le message
    Sauf erreur, ta requête ne fonctionne que s'il n'y a qu'un seul enregistrement dans t1 qui référence t2.
    oui, bonne remarque

  7. #7
    Membre actif Avatar de speedy_g
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    213
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2007
    Messages : 213
    Points : 242
    Points
    242
    Par défaut
    @xdescamp et laurentschneider

    La requête fonctionne pour autant qu'il n'y aie qu'au plus un élément de table 1 dans chaque élément de table 2,
    i.e le jeu de valeurs ainsi modifié ne produit plus de résultats corrects.
    Il est toujours possible de mettre un 'select distinct' en en-tête mais pour 2300 records celle-ci met 0.6 secondes pour être effectuée.
    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
     
    WITH table_1 AS (SELECT 1 id, 5 id_tbl2 FROM dual union ALL
                     SELECT 2 id, 1 id_tbl2 FROM dual union ALL
                    SELECT  3 id, 1 id_tbl2 FROM dual),
         table_2 AS (SELECT 1 id, 0 id_parent, 'dec1' description FROM dual union ALL
                     SELECT 2 id, 1 id_parent, 'dec2' description FROM dual union ALL
                     SELECT 5 id, 2 id_parent, 'dec3' description FROM dual union ALL
                     SELECT 0 id, NULL id_parent, 'root' description FROM dual)
    SELECT connect_by_root id_1, id_2, description
    FROM (SELECT table_1.id id_1, table_2.id id_2, table_2.id_parent id_parent_2, table_2.description
          FROM table_1,
               table_2
          WHERE table_2.id = table_1.id_tbl2(+))
    Connect BY prior id_parent_2 = id_2
    start WITH id_1 IS NOT NULL;
    La requête de Waldar fonctionne quand à elle assez bien.

    Par pure curiosité, que faudrait-il faire pour que la requête fonctionne ?.

    Merci en tout cas pour votre aide.


    Johan

  8. #8
    Membre averti Avatar de xdescamp
    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 300
    Points : 442
    Points
    442
    Par défaut
    Effectivement, quand il y a plusieurs éléments dans table_1, la partie hiérarchique de la requête ne fonctionne plus.

    Là comme ça je ne vois pas trop comment on pourrait la corriger.
    L'option de Waldar consistant à faire la partie hiérarchique tout de suite me paraît une meilleure option.

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

Discussions similaires

  1. Requete SQL sur condition aléatoire
    Par Jey25 dans le forum Requêtes
    Réponses: 7
    Dernier message: 04/02/2006, 20h51
  2. [SQL] Requete contenant plusieurs conditions
    Par dj-julio dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 17/01/2006, 01h24
  3. Requete Left join
    Par nicodour dans le forum Requêtes
    Réponses: 5
    Dernier message: 29/12/2005, 16h23
  4. [LEFT JOIN] Condition de jointure bizzare
    Par Celelibi dans le forum Requêtes
    Réponses: 7
    Dernier message: 17/05/2005, 18h38
  5. Erreur lors d'une requete INNER JOIN
    Par k-lendos dans le forum Langage SQL
    Réponses: 2
    Dernier message: 17/03/2004, 15h09

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