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 :

optimisation de requête avec plusieurs union


Sujet :

SQL Oracle

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    568
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 568
    Points : 167
    Points
    167
    Par défaut optimisation de requête avec plusieurs union
    Bonjour,
    je souhaite optimiser la requête suivante:
    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    select distinct p.NIP,/* VARCHAR2 */
    p.NOM,/* VARCHAR2*/ 
    p.PRENOM,/* VARCHAR2 */
    sj.DATE_ENT,/* NUMBER */
    q3.NIQ,/* NUMBER */
    q3.LIBABR, /* VARCHAR2 */
    NULL,
    q3.TYPEQ /* NUMBER */
    from PENSOINS.BM_LIB_S lib2,
    PENSOINS.C_QUESTION q3,
    PENSOINS.PATIENT p,
    PENSOINS.SEJOUR sj,
    PENSOINS.BM_TH_S th
    where lib2.NITH = th.NITH
    and lib2.PARENTE like '674,%'
    and p.NIPATIENT = sj.NIPATIENT 
    and sj.NISEJOUR = th.NISEJOUR
    and th.NIQUEST = q3.NIQUEST
    and (q3.LIBABR like 'IDENTITE%'
    or q3.LIBABR like 'Tabac'
    or q3.LIBABR like 'Protocole de recherche%'
    or q3.LIBABR like 'Adéquation de la prescription%'
    or q3.LIBABR like 'Pathologie respiratoire'
    or q3.LIBABR like 'Pathologie extra-pulmonaire'
    or q3.LIBABR like 'Antécédents%'
    or q3.LIBABR like 'Traitement médicamenteux%'
    or q3.LIBABR like 'SIGNES FONCTIONNELS%'
    or q3.LIBABR like 'Toux - Expectoration%'
    or q3.LIBABR like 'Dyspnée%'
    or q3.LIBABR like 'Score qualité de vie : SF-36%'
    or q3.LIBABR like 'SPIRO-RESIS VA%'
    or q3.LIBABR like 'Conclusion EFR%')
    UNION 
    SELECT distinct p.NIP, /* VARCHAR2 */
    p.NOM, /* VARCHAR2*/ 
    p.PRENOM, /* VARCHAR2 */
    sj.DATE_ENT, /* NUMBER */
    8341.5,/* NUMBER */
    'fumeur', /* VARCHAR2 */
    NULL,
    0/* NUMBER */
    FROM PENSOINS.BM_LIB_S lib2,
    PENSOINS.C_QUESTION q3,
    PENSOINS.PATIENT p,
    PENSOINS.SEJOUR sj,
    PENSOINS.BM_TH_S th
    where lib2.NITH = th.NITH
    and lib2.PARENTE like '674,%'
    and p.NIPATIENT = sj.NIPATIENT 
    and sj.NISEJOUR = th.NISEJOUR
    and th.NIQUEST = q3.NIQUEST
    UNION 
    SELECT distinct p.NIP, /* VARCHAR2 */
    p.NOM, /* VARCHAR2*/ 
    p.PRENOM, /* VARCHAR2 */
    sj.DATE_ENT, /* NUMBER */
    8342.5,/* NUMBER */
    'fumeur de cigarettes', /* VARCHAR2 */
    NULL,
    0/* NUMBER */
    FROM PENSOINS.BM_LIB_S lib2,
    PENSOINS.C_QUESTION q3,
    PENSOINS.PATIENT p,
    PENSOINS.SEJOUR sj,
    PENSOINS.BM_TH_S th
    where lib2.NITH = th.NITH
    and lib2.PARENTE like '674,%'
    and p.NIPATIENT = sj.NIPATIENT 
    and sj.NISEJOUR = th.NISEJOUR
    and th.NIQUEST = q3.NIQUEST
    comme vous pouvez constatez, je suis obligé de faire autant de duplication que d'Union, vous imaginez donc ma requête après 10 unions !!

    j'ai essayé d'utiliser DUAL mais apparemment ça marche pas quand il y'a des jointures!!

    quecun aurai une idée de comment faire dans ce cas.

    je veous remercie d'vance pour votre aide.

  2. #2
    Membre éprouvé Avatar de Yorglaa
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    845
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2004
    Messages : 845
    Points : 931
    Points
    931
    Par défaut
    tu pourrais poser ton problème un peu plus clairement STP ?

    parce que là, si je te résume tu as un select qui fonctionne, mais tu voudrais l'optimiser...
    certes mais encore ?

    oui tu as des union... mais ? on ne sait même pas ce qui change dans tes requêtes pour justifer des union...

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    568
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 568
    Points : 167
    Points
    167
    Par défaut
    désolé, je m'explique:
    en fait dans les deux dernière requête j'ai la même partie qui se repéte:
    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
    SELECT distinct p.NIP, /* VARCHAR2 */
    p.NOM, /* VARCHAR2*/ 
    p.PRENOM, /* VARCHAR2 */
    sj.DATE_ENT, /* NUMBER */
    8341.5,/* NUMBER */
    'fumeur', /* VARCHAR2 */
    NULL,
    0/* NUMBER */
    FROM PENSOINS.BM_LIB_S lib2,
    PENSOINS.C_QUESTION q3,
    PENSOINS.PATIENT p,
    PENSOINS.SEJOUR sj,
    PENSOINS.BM_TH_S th
    where lib2.NITH = th.NITH
    and lib2.PARENTE like '674,%'
    and p.NIPATIENT = sj.NIPATIENT 
    and sj.NISEJOUR = th.NISEJOUR
    and th.NIQUEST = q3.NIQUEST
    UNION 
    SELECT distinct p.NIP, /* VARCHAR2 */
    p.NOM, /* VARCHAR2*/ 
    p.PRENOM, /* VARCHAR2 */
    sj.DATE_ENT, /* NUMBER */
    8342.5,/* NUMBER */
    'fumeur de cigarettes', /* VARCHAR2 */
    NULL,
    0/* NUMBER */
    FROM PENSOINS.BM_LIB_S lib2,
    PENSOINS.C_QUESTION q3,
    PENSOINS.PATIENT p,
    PENSOINS.SEJOUR sj,
    PENSOINS.BM_TH_S th
    where lib2.NITH = th.NITH
    and lib2.PARENTE like '674,%'
    and p.NIPATIENT = sj.NIPATIENT 
    and sj.NISEJOUR = th.NISEJOUR
    and th.NIQUEST = q3.NIQUEST
    c'est à dire que si encore j'ajoute d'autre union, j'aurai toujours la même partie en gras qui se répéte.
    je pense qu'il doit exister un moyen pour executer cette partie une fois et de pouvoir la réutiliser après, mais j'avoue que je ne sais pas comment

    merci encore

  4. #4
    Membre éprouvé Avatar de Yorglaa
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    845
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2004
    Messages : 845
    Points : 931
    Points
    931
    Par défaut
    alors tu peux utiliser la clause WITH, comme 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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    With
        TOTO as ( -- n'importe quel nom... TOTO c'est pas obligé !
                    Select
                            xxx -- les colonnes dont tu as besoin 
                    From    
                            PENSOINS.BM_LIB_S lib2
                            , PENSOINS.C_QUESTION q3
                            , PENSOINS.PATIENT p
                            , PENSOINS.SEJOUR sj
                            , PENSOINS.BM_TH_S th
                    Where   lib2.NITH = th.NITH
                    And     lib2.PARENTE like '674,%'
                    And     p.NIPATIENT = sj.NIPATIENT 
                    And     sj.NISEJOUR = th.NISEJOUR
                    And     th.NIQUEST = q3.NIQUEST
                )
    Select
            yyy -- toujours les colonnes dont tu as besoin
            'n''importe quelle autre chose'
            , blabla
    From
            TOTO
    Where   blablabla -- clause spécifique à cette partie du union 
    UNION
    Select
            yyy -- toujours les colonnes dont tu as besoin
            'n''importe quelle autre chose'
            , blabla
    From
            TOTO
    Where   blablabla -- clause spécifique à cette partie du union 
    UNION
    Select
            yyy -- toujours les colonnes dont tu as besoin
            'n''importe quelle autre chose'
            , blabla
    From
            TOTO
    Where   blablabla -- clause spécifique à cette partie du union

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 750
    Points : 341
    Points
    341
    Par défaut
    Pour éviter les tri effectués par les UNION tu peux utiliser UNION ALL...ça va beaucoup plus vite...Sauf si t'as besoin d'enlever les doublons auquel cas t'es obligé d'utiliser UNION

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    568
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 568
    Points : 167
    Points
    167
    Par défaut
    merci beaucoup, j'ai appliqué exactement ce que tu m'as conseillé:
    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    WITH
        TITRE AS (
                    SELECT  p.NIP,/* VARCHAR2 */
                            p.NOM,/* VARCHAR2*/ 
                            p.PRENOM,/* VARCHAR2 */
                            sj.DATE_ENT,/* NUMBER */
                            q3.NIQ,/* NUMBER */
                            q3.LIBABR, /* VARCHAR2 */
                            NULL,
                            q3.TYPEQ /* NUMBER */
                    FROM    
                            PENSOINS.BM_LIB_S lib2,
                            PENSOINS.C_QUESTION q3,
                            PENSOINS.PATIENT p,
                            PENSOINS.SEJOUR sj,
                            PENSOINS.BM_TH_S th
                    WHERE   lib2.NITH = th.NITH
                            AND  lib2.PARENTE LIKE '674,%'
                            AND  p.NIPATIENT = sj.NIPATIENT 
                            AND  sj.NISEJOUR = th.NISEJOUR
                            AND  th.NIQUEST = q3.NIQUEST
                )
    SELECT  p.NIP,/* VARCHAR2 */
            p.NOM,/* VARCHAR2*/ 
            p.PRENOM,/* VARCHAR2 */
            sj.DATE_ENT,/* NUMBER */
            q3.NIQ,/* NUMBER */
            q3.LIBABR, /* VARCHAR2 */
            NULL,
            q3.TYPEQ /* NUMBER */
    FROM
            TITRE
    WHERE   q3.LIBABR like 'IDENTITE%'
            or q3.LIBABR like 'Tabac'
            or q3.LIBABR like 'Protocole de recherche%'
            or q3.LIBABR like 'Adéquation de la prescription%'
            or q3.LIBABR like 'Pathologie respiratoire'
            or q3.LIBABR like 'Pathologie extra-pulmonaire'
            or q3.LIBABR like 'Antécédents%'
            or q3.LIBABR like 'Traitement médicamenteux%'
            or q3.LIBABR like 'SIGNES FONCTIONNELS%'
            or q3.LIBABR like 'Toux - Expectoration%'
            or q3.LIBABR like 'Dyspnée%'
            or q3.LIBABR like 'Score qualité de vie : SF-36%'
            or q3.LIBABR like 'SPIRO-RESIS VA%'
            or q3.LIBABR like 'Conclusion EFR%'
    UNION
    SELECT  p.NIP, /* VARCHAR2 */
            p.NOM, /* VARCHAR2*/ 
            p.PRENOM, /* VARCHAR2 */
            sj.DATE_ENT, /* NUMBER */
            8341.5,/* NUMBER */
            'fumeur', /* VARCHAR2 */
            NULL,
            0/* NUMBER */
    FROM
            TITRE
    UNION
    SELECT  p.NIP, /* VARCHAR2 */
            p.NOM, /* VARCHAR2*/ 
            p.PRENOM, /* VARCHAR2 */
            sj.DATE_ENT, /* NUMBER */
            8346.5,/* NUMBER */
            'fumeur', /* VARCHAR2 */
            NULL,
            0/* NUMBER */
    FROM
            TITRE
    UNION
    SELECT  p.NIP, /* VARCHAR2 */
            p.NOM, /* VARCHAR2*/ 
            p.PRENOM, /* VARCHAR2 */
            sj.DATE_ENT, /* NUMBER */
            8349.5,/* NUMBER */
            'fumeur', /* VARCHAR2 */
            NULL,
            0/* NUMBER */
    FROM
            TITRE
    UNION
    SELECT  p.NIP, /* VARCHAR2 */
            p.NOM, /* VARCHAR2*/ 
            p.PRENOM, /* VARCHAR2 */
            sj.DATE_ENT, /* NUMBER */
            8352.5,/* NUMBER */
            'fumeur', /* VARCHAR2 */
            NULL,
            0/* NUMBER */
    FROM
            TITRE
    UNION
    SELECT  p.NIP, /* VARCHAR2 */
            p.NOM, /* VARCHAR2*/ 
            p.PRENOM, /* VARCHAR2 */
            sj.DATE_ENT, /* NUMBER */
            8354.5,/* NUMBER */
            'fumeur', /* VARCHAR2 */
            NULL,
            0/* NUMBER */
    FROM
            TITRE
    mais je ne sais pas pour quoi il reconnait pas certaines colonnes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ORA-00904: "Q3"."LIBABR": invalid identifier
    merci encore pour votre aide

  7. #7
    Membre éprouvé Avatar de Yorglaa
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    845
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2004
    Messages : 845
    Points : 931
    Points
    931
    Par défaut
    ben ta colonne ne s'appelle plus "Q3"."LIBABR" mais "TITRE"."LIBABR"
    et aussi la colonne à Null que tu mets dans TITRE... y'en a pas besoin !

    insère la valeur voulue directement dans les Select du UNION

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    568
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 568
    Points : 167
    Points
    167
    Par défaut
    oui oui, je me suis rendu compte juste après; désolé
    par contre ça met très long temps pour s'executer quand même.
    Je vais essayer d'optimiser encore plus ma requête avant de mettre resolu à ce poste.

    merci encore

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 750
    Points : 341
    Points
    341
    Par défaut
    Citation Envoyé par Smix007 Voir le message
    oui oui, je me suis rendu compte juste après; désolé
    par contre ça met très long temps pour s'executer quand même.
    Je vais essayer d'optimiser encore plus ma requête avant de mettre resolu à ce poste.

    merci encore
    je me répète: essaye le UNION ALL

  10. #10
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    En effet, le UNION force un distinct sur le résultat.
    Ici, tu as le libellé ('Fumeur', 'Fumeur de cigarette') qui est différent entre les 2 requetes.

    Et si c'est juste pour dupliquer les lignes :
    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
    SELECT a.nip, a.nom, a.prenom, a.date_ent, b.code, b.libelle, NULL, 0
    FROM (
        SELECT DISTINCT p.NIP, p.NOM, p.PRENOM, sj.DATE_ENT, 
        FROM PENSOINS.BM_LIB_S lib2,
            PENSOINS.C_QUESTION q3,
            PENSOINS.PATIENT p,
            PENSOINS.SEJOUR sj,
            PENSOINS.BM_TH_S th
        WHERE lib2.nith = th.nith
        AND lib2.parente LIKE '674,%'
        AND p.nipatient = sj.nipatient 
        AND sj.nisejour = th.nisejour
        AND th.niquest = q3.niquest) A,
        (SELECT 8341.5 AS code, 'fumeur' AS libelle FROM DUAL
        UNION ALL 
        SELECT 8342.5 AS code, 'fumeur de cigarettes' AS libelle FROM DUAL
        ) b

  11. #11
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    568
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 568
    Points : 167
    Points
    167
    Par défaut
    ouiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii , elle met moins de temps.
    je vous remercie encore.

    merci beaucoup pour votre aide

  12. #12
    Expert éminent sénior 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
    Points : 11 252
    Points
    11 252
    Par défaut
    Ou encore
    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
     
    SELECT a.nip, a.nom, a.prenom, a.date_ent, b.code, b.libelle, NULL, 0
    FROM (
        SELECT DISTINCT p.NIP, p.NOM, p.PRENOM, sj.DATE_ENT, 
        FROM PENSOINS.BM_LIB_S lib2,
            PENSOINS.C_QUESTION q3,
            PENSOINS.PATIENT p,
            PENSOINS.SEJOUR sj,
            PENSOINS.BM_TH_S th
        WHERE lib2.nith = th.nith
        AND lib2.parente LIKE '674,%'
        AND p.nipatient = sj.nipatient 
        AND sj.nisejour = th.nisejour
        AND th.niquest = q3.niquest) A,
        (Select Case When level = 1 Then 8341.5 
                     When level = 2 Then 8342.5 
                End code,
                Case When level = 1 Then 'fumeur' 
                     When level = 2 Then 'fumeur de cigarettes' 
                End libelle
          From dual Connect By level <= 2) b

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

Discussions similaires

  1. [Cours pt-02][Débutants]Requête avec plusieurs sommes
    Par Papy Turbo dans le forum Sondages et Débats
    Réponses: 18
    Dernier message: 29/10/2007, 18h55
  2. Réponses: 4
    Dernier message: 29/06/2006, 10h11
  3. [CF][C#] Comment optimiser mes requêtes avec SqlCE ?
    Par david71 dans le forum Windows Mobile
    Réponses: 10
    Dernier message: 20/01/2006, 14h48
  4. une requête avec plusieurs INNER JOIN, cmt faire ?
    Par elhosni dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 10/01/2006, 17h55
  5. Optimisation de requête avec Tkprof
    Par stingrayjo dans le forum Oracle
    Réponses: 3
    Dernier message: 04/07/2005, 09h50

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