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 :

requetes hiérarchiques et somme [9i]


Sujet :

SQL Oracle

  1. #1
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2002
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2002
    Messages : 72
    Par défaut requetes hiérarchiques et somme [9i]
    Voila je suis en 9i et je fait des requetes hiérarchique sur une table, jusque la pas de soucci.
    Mon arbres est constitué d'elements qui ont tous un délai, j'aimerai cumulé ces délais sur mes branches les plus hautes.
    il s'agit donc de trouver un chemin critique.
    exemple :
    si tous les element ont 1 en délai, j'aimerai une requete qui me ramenne :
    sur le 11 et le 21 : 1 sur le 1et 2 : 2 et sur le 0 : 3

    es ce possible en 1 seul requete en 9i ?

    merci.

  2. #2
    Membre Expert Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Par défaut
    Désolé ... erreur de compréhension de ma part

  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
    Par défaut
    • test data

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    create table t as (
            select  0 child,null parent from dual union all
            select 1,0 from dual union all
            select 2,0 from dual union all
            select 11,1 from dual union all
            select 21,2 from dual )
    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
    select child, max(l) from
    (select child, level l  
    from t 
    connect by prior parent=child 
    )
    group by child
    order by 2
     
         CHILD     MAX(L)
    ---------- ----------
            21          1
            11          1
             1          2
             2          2
             0          3

  4. #4
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 : 5 611
    Par défaut
    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
     
    Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 
    Connected as mni
     
    SQL> 
    SQL> With data as
      2  (
      3    Select 0 As id, null as parent_id, 0 as delai from dual union all
      4    Select 1 As id, 0 as parent_id, 1 as delai from dual union all
      5    Select 2 As id, 0 as parent_id, 2 as delai from dual union all
      6    Select 11 As id, 1 as parent_id, 2 as delai from dual union all
      7    Select 21 As id, 2 as parent_id, 3 as delai from dual
      8  )
      9  Select id, parent_id, (Select Sum(delai)
     10                           From data b
     11                          Where id In (Select id
     12                                         From data c
     13                                        connect by prior id = parent_id
     14                                        start with id = a.id)
     15                        ) Sum_delai
     16    From data a
     17  /
     
            ID  PARENT_ID  SUM_DELAI
    ---------- ---------- ----------
             0                     8
             1          0          3
             2          0          5
            11          1          2
            21          2          3
     
    SQL>
    Mais dpv perf ça peut être vite la Berezina.

  5. #5
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2002
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2002
    Messages : 72
    Par défaut
    en fait c'est le chemin crique qu'il me faut, pas le total de tous :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
         ID  PARENT_ID  SUM_DELAI
    ---------- ---------- ----------
             0                     8
             1          0          3
             2          0          5
            11          1          2
            21          2          3
    donc pour le 0 ce serai 0+1+2 (coté element 1) soit 3
    et 0+2+3 (coté element 2) soit 5
    donc un total de 5.
    quand t'on a une seul branche t'a requete marche tres bien.

    pour laurentschneider merci, mais mon probleme est la somme des délais.

  6. #6
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 : 5 611
    Par défaut
    Maintenant c'est Waterloo
    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
    Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 
    Connected as mni
     
    SQL> 
    SQL> WITH DATA AS
      2  (
      3    SELECT 0 AS id, NULL AS parent_id, 0 AS delai FROM dual union ALL
      4    SELECT 1 AS id, 0 AS parent_id, 1 AS delai FROM dual union ALL
      5    SELECT 2 AS id, 0 AS parent_id, 2 AS delai FROM dual union ALL
      6    SELECT 11 AS id, 1 AS parent_id, 2 AS delai FROM dual union ALL
      7    SELECT 21 AS id, 2 AS parent_id, 3 AS delai FROM dual union ALL
      8    SELECT 100 AS id, NULL AS parent_id, 0 AS delai FROM dual union ALL
      9    SELECT 101 AS id, 100 AS parent_id, 7 AS delai FROM dual union ALL
     10    SELECT 102 AS id, 100 AS parent_id, 1 AS delai FROM dual union ALL
     11    SELECT 1011 AS id, 101 AS parent_id, 4 AS delai FROM dual union ALL
     12    SELECT 1021 AS id, 102 AS parent_id, 8 AS delai FROM dual
     13  ),
     14  Calc_Data As
     15  (
     16    SELECT id, parent_id, (SELECT Sum(delai)
     17                             FROM DATA b
     18                            WHERE id IN (SELECT id
     19                                           FROM DATA c
     20                                          connect BY prior id = parent_id
     21                                          start WITH id = a.id)
     22                           ) Sum_delai
     23      FROM DATA a
     24  )
     25  Select id, parent_id,
     26         Case When parent_id Is Null Then (Select Max(Sum_delai)
     27                                             From Calc_Data b
     28                                            Where parent_id = a.id)
     29         Else Sum_Delai
     30         End delai
     31    From Calc_data a
     32  /
     
            ID  PARENT_ID      DELAI
    ---------- ---------- ----------
             0                     5
             1          0          3
             2          0          5
            11          1          2
            21          2          3
           100                    11
           101        100         11
           102        100          9
          1011        101          4
          1021        102          8
     
    10 rows selected
     
    SQL>

  7. #7
    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
    Par défaut
    avec 2 petites fonctions (en 10g il y aurait le connect_by_root)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE OR REPLACE FUNCTION eval (str VARCHAR2)
       RETURN NUMBER
    IS
       n   NUMBER;
    BEGIN
       EXECUTE IMMEDIATE 'begin :n := ' || str || ';end;' USING OUT n;
     
       RETURN n;
    END;
    /
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CREATE OR REPLACE FUNCTION root (str VARCHAR2)
       RETURN VARCHAR2
    IS
    BEGIN
       RETURN SUBSTR (str, 2, INSTR (str || '/', '/', 2) - 2);
    END;
    /
    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
    WITH t
         AS (SELECT 0 id, NULL parent, 0 delai FROM DUAL
             UNION ALL
             SELECT 1, 0, 1 FROM DUAL
             UNION ALL
             SELECT 2, 0, 2 FROM DUAL
             UNION ALL
             SELECT 11, 1, 2 FROM DUAL
             UNION ALL
             SELECT 21, 2, 3 FROM DUAL)
      SELECT root, MAX (PATH)
        FROM (    SELECT root (SYS_CONNECT_BY_PATH (id, '/')) root,
                         eval (SYS_CONNECT_BY_PATH (delai, '+')) PATH
                    FROM t
              CONNECT BY parent = PRIOR id)
    GROUP BY root;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ROOT MAX(PATH)
    ---- ---------
    1            3
    11           2
    21           3
    0            5
    2            5

  8. #8
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2002
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2002
    Messages : 72
    Par défaut
    mnitu : joli
    (y a l'element 0 si on ajout un délai c'est pas pris en compte, mais je chipote, je vais trouver) un grand merci a toi !

    laurentschneider : oui on doit passer en 11 d'ici quelques mois, mais mon projet est déja en cours.

  9. #9
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 : 5 611
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Case When parent_id IS NULL Then delai + (SELECT Max(Sum_delai)...
    Mais côté perf ça va seulement pour des petits volumétries.

  10. #10
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2002
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2002
    Messages : 72
    Par défaut
    4Millions d'enregistrements : oui ça va c'est pas trop gros, et de toutes façon je filtre ! encore merci a toi.

  11. #11
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2002
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2002
    Messages : 72
    Par défaut
    En fait ce code ne peut pas convenir a mes besoins, en effet la separation des branches ne se fait pas forcement sur le niveau le plus haut, mais peu se produire plus "bas" dans l'arbre.
    par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT 0 AS id, NULL AS parent_id, 5 AS delai FROM dual union ALL
          SELECT 1 AS id, 0 AS parent_id, 10 AS delai FROM dual union ALL
          SELECT 11 AS id, 1 AS parent_id, 5 AS delai FROM dual union ALL
          SELECT 111 AS id, 11 AS parent_id, 5 AS delai FROM dual union ALL
          SELECT 3 AS id, 0 AS parent_id, 9 AS delai FROM dual union ALL
         SELECT 31 AS id, 3 AS parent_id, 0 AS delai FROM dual union ALL
          SELECT 311 AS id, 31  AS parent_id, 1 AS delai FROM dual union ALL
         SELECT 312 AS id, 31 AS parent_id, 1 AS delai FROM dual union ALL
         SELECT 313 AS id, 31 AS parent_id, 1 AS delai FROM dual union ALL
         SELECT 5 AS id, 0 AS parent_id, 10 AS delai FROM dual  union ALL
          SELECT 51 AS id, 5 AS parent_id, 5 AS delai FROM dual union ALL
           SELECT 511 AS id, 51 AS parent_id, 5 AS delai FROM dual
    et pour le coup, l'element 3 ne doit pas avoir un délai de 12 mais bien de 10.

    et au niveau du code cela donne :
    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
       SELECT id, parent_id,
               Case When parent_id IS NULL Then delai +  (SELECT Max(Sum_delai)
                                                  FROM  (  SELECT id, parent_id, (SELECT Sum(delai)
                                  FROM adv_dev_cde.simu_nomenclature b
                                 WHERE id IN (SELECT id
                                                FROM adv_dev_cde.simu_nomenclature c
                                               connect BY prior id = parent_id
                                               start WITH id = a.id)
                                ) Sum_delai,delai
           FROM adv_dev_cde.simu_nomenclature a) b
                                                WHERE parent_id = a.id)
              Else Sum_Delai
             End delai
       FROM  (
         SELECT id, parent_id, (SELECT Sum(delai)
                                  FROM adv_dev_cde.simu_nomenclature b
                                 WHERE id IN (SELECT id
                                                FROM adv_dev_cde.simu_nomenclature c
                                               connect BY prior id = parent_id
                                               start WITH id = a.id)
                                ) Sum_delai,delai
           FROM adv_dev_cde.simu_nomenclature a
       ) a;

  12. #12
    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
    Par défaut
    tu as essayé mon code???

    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 t as (
    SELECT 0 AS id, NULL AS parent_id, 5 AS delai FROM dual union ALL
          SELECT 1 AS id, 0 AS parent_id, 10 AS delai FROM dual union ALL
          SELECT 11 AS id, 1 AS parent_id, 5 AS delai FROM dual union ALL
          SELECT 111 AS id, 11 AS parent_id, 5 AS delai FROM dual union ALL
          SELECT 3 AS id, 0 AS parent_id, 9 AS delai FROM dual union ALL
         SELECT 31 AS id, 3 AS parent_id, 0 AS delai FROM dual union ALL
          SELECT 311 AS id, 31  AS parent_id, 1 AS delai FROM dual union ALL
         SELECT 312 AS id, 31 AS parent_id, 1 AS delai FROM dual union ALL
         SELECT 313 AS id, 31 AS parent_id, 1 AS delai FROM dual union ALL
         SELECT 5 AS id, 0 AS parent_id, 10 AS delai FROM dual  union ALL
          SELECT 51 AS id, 5 AS parent_id, 5 AS delai FROM dual union ALL
           SELECT 511 AS id, 51 AS parent_id, 5 AS delai FROM dual
           )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
           SELECT root, MAX (PATH)
        FROM (    SELECT root (SYS_CONNECT_BY_PATH (id, '/')) root,
                         eval (SYS_CONNECT_BY_PATH (delai, '+')) PATH
                    FROM t
              CONNECT BY parent_id = PRIOR id)
    GROUP BY root;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    ROOT MAX(PATH)              
    ---- ---------------------- 
    1    20                     
    3    10                     
    11   10                     
    312  1                      
    511  5                      
    31   1                      
    311  1                      
    313  1                      
    51   10                     
    0    25                     
    5    20                     
    111  5

  13. #13
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2002
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2002
    Messages : 72
    Par défaut
    c'est gentil laurentschneider , mais je suis en 9i, donc j'ai pas ces fonctions la.
    et pas de possibilité d'évoluer pour le moment.
    je vais faire une requete + simple + une fonction, je la posterai quand je l'aurai fini.

  14. #14
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    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 : 5 611

  15. #15
    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
    Par défaut
    je t'ai posté le code des fonctions, relis ma réponse stpl

  16. #16
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2002
    Messages
    72
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2002
    Messages : 72
    Par défaut
    ok merci beaucoup, j'avais trouvé avec une fonction, mais la tienne est beaucoup plus efficace (-de code).

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

Discussions similaires

  1. [AC-2003] Requete regroupement et somme
    Par jokair dans le forum Access
    Réponses: 6
    Dernier message: 02/05/2011, 16h59
  2. Requete regroupement et somme
    Par @rkane dans le forum Requêtes et SQL.
    Réponses: 5
    Dernier message: 15/04/2011, 14h16
  3. requetes imbriquees et sommes
    Par cannelline dans le forum Langage SQL
    Réponses: 5
    Dernier message: 22/09/2008, 17h39
  4. [Requete] Faire une somme puis une moyenne
    Par Mou dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 14/05/2007, 10h09
  5. Réponses: 2
    Dernier message: 09/01/2006, 16h10

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