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

Oracle Discussion :

requête avec jointure externe


Sujet :

Oracle

  1. #1
    Membre actif

    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 87
    Points : 281
    Points
    281
    Par défaut requête avec jointure externe
    bonjour,

    j'ai qq problèmes pour effectuer la jointure externe sur 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
    select L.NUM_TOUR			,
    	 L.NUM_LIG_TOUR		,
    	 C.EMP			EMP,
    	 C.NUM_CONT			NUM_CONT,
    	 C.NUM_ART			NUM_ART,
    	 C.NUM_LOT			NUM_LOT,
    	 C.DLUO			DLUO
      from LIG_TOUR L, CONTENANT C, CR_STOCK CR
     where CR.NUM_LIG_TOUR		= L.NUM_LIG_TOUR(+)
       and CR.NUM_ART			= C.NUM_ART(+)
       and L.TYP_TOUR			= 'INV'
       and L.TYP_REAL			= 'PAPI'
       and L.STYP_TOUR		= 'ACON'
       and C.NUM_LIG_TOUR_INV	= L.NUM_LIG_TOUR
       and L.ETAT_LIG_TOUR		= 'LANC'
       and CR.NUM_TOUR		= L.NUM_TOUR
       and CR.NUM_CONT		= C.NUM_CONT
       and CR.ETAT_CR_STOCK		!= 'TERM';
    la jointure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    and CR.NUM_ART			= C.NUM_ART(+)
    ne fonctionne pas alors que mon C.NUM_ART existe bien lorsque je fais la même requête sans la clause citée précédemment, c'est-à-dire :

    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 L.NUM_TOUR			,
    	 L.NUM_LIG_TOUR		,
    	 C.EMP			EMP,
    	 C.NUM_CONT			NUM_CONT,
    	 C.NUM_ART			NUM_ART,
    	 C.NUM_LOT			NUM_LOT,
    	 C.DLUO			DLUO
      from LIG_TOUR L, CONTENANT C, CR_STOCK CR
     where CR.NUM_LIG_TOUR		= L.NUM_LIG_TOUR(+)
       and L.TYP_TOUR			= 'INV'
       and L.TYP_REAL			= 'PAPI'
       and L.STYP_TOUR		= 'ACON'
       and C.NUM_LIG_TOUR_INV	= L.NUM_LIG_TOUR
       and L.ETAT_LIG_TOUR		= 'LANC'
       and CR.NUM_TOUR		= L.NUM_TOUR
       and CR.NUM_CONT		= C.NUM_CONT
       and CR.ETAT_CR_STOCK		!= 'TERM';
    merci d'avance pour vos conseils

  2. #2
    Membre averti

    Inscrit en
    Septembre 2003
    Messages
    425
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 425
    Points : 398
    Points
    398
    Par défaut
    Tu as une très jolie boucle dans tes jointures :

    1) Tu lies CR à L(+) et CR à C(+)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    where CR.NUM_LIG_TOUR      = L.NUM_LIG_TOUR(+) 
    and CR.NUM_ART         = C.NUM_ART(+)
    2) il faudrait aussi ouvrir les autres jointures

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    and CR.NUM_TOUR      = L.NUM_TOUR 
    and CR.NUM_CONT      = C.NUM_CONT
    3) il faudrait aussi ouvrir les restrictions (si tu m'a pas correspondance dans LIG_TOUR L, tu ne peux avoir une valeur à tester !) Sinon la jointure externe ne sert à rien

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    and L.TYP_TOUR(+)         = 'INV' 
    and L.TYP_REAL(+)         = 'PAPI' 
    and L.STYP_TOUR(+)      = 'ACON' 
    and L.ETAT_LIG_TOUR(+)      = 'LANC'
    4) Ce qui m'embête c'est que tu lie aussi C à L , alors tu as une boucle car CR est lié à L et C et C est lié à L ? Mais c'est peut ê une spécificité de ton schéma, c'est assez dur à voir

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    and C.NUM_LIG_TOUR_INV   = L.NUM_LIG_TOUR
    Mais commence par ouvrir toutes les jointures, puis les test sur les jointures et ensuite tu me réponderas au point 4

    Tu peux faire un test avec ces 2 requêtes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    with acteur as (
    select 1 num_act from dual
    union 
    select 2 num_act from dual)
    , movie as (
    select 1 num_act, 'FIL1' film from dual union
    select 1 num_act, 'mon père ce héros' film from dual
    )
    select act.num_act, mov.film
    from acteur act, movie mov
    where act.num_act = mov.num_act(+)
    and film(+) = 'FIL1'
    Ramene les acteurs même sans film, et les acteurs remenés juste ceux qui ont joués dans le film FIL1

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    with acteur as (
    select 1 num_act from dual
    union 
    select 2 num_act from dual)
    , movie as (
    select 1 num_act, 'FIL1' film from dual union
    select 1 num_act, 'mon père ce héros' film from dual
    )
    select act.num_act, mov.film
    from acteur act, movie mov
    where act.num_act = mov.num_act(+)
    and film = 'FIL1'
    Ramene que les acteurs qui ont joués dans FIL1, dc pas besoin de joitnure externe dans ce cas, il faudrait faire une joitnure normale tel que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    where act.num_act = mov.num_act

  3. #3
    Membre actif

    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 87
    Points : 281
    Points
    281
    Par défaut
    tout d'abord, merci d'avoir répondu

    ce que tu m'expliques m'a fait pas mal réfléchir sur la question.
    en réalité je viens de me rendre compte que mon (+) était mal placé:

    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
    select L.NUM_TOUR			,
    	 L.NUM_LIG_TOUR		,
    	 C.EMP			EMP,
    	 C.NUM_CONT			NUM_CONT,
    	 C.NUM_ART			NUM_ART,
    	 C.NUM_LOT			NUM_LOT,
    	 C.DLUO			DLUO
      from LIG_TOUR L, CONTENANT C, CR_STOCK CR
     where CR.NUM_LIG_TOUR		= L.NUM_LIG_TOUR(+)
       and CR.NUM_TOUR		= L.NUM_TOUR
       and CR.NUM_ART	(+)		= C.NUM_ART
       and CR.NUM_CONT (+)		= C.NUM_CONT
       and L.TYP_TOUR			= 'INV'
       and L.TYP_REAL			= 'PAPI'
       and L.STYP_TOUR		= 'ACON'
       and L.ETAT_LIG_TOUR		= 'LANC'
       and C.NUM_LIG_TOUR_INV	= L.NUM_LIG_TOUR
       and CR.ETAT_CR_STOCK		!= 'TERM';

    c'est le CR.NUM_ART qui est facultatif. j'ai essayé d'ajouter les (+) sur les autres clauses de la jointure, mais ça ne semble pas fonctionner.

  4. #4
    Membre averti

    Inscrit en
    Septembre 2003
    Messages
    425
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 425
    Points : 398
    Points
    398
    Par défaut
    Pour moi ca c'est pas logique
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    where CR.NUM_LIG_TOUR      = L.NUM_LIG_TOUR(+) 
    and CR.NUM_TOUR      = L.NUM_TOUR
    Tu lies tes stocks à tes lignes en ouvrant qu'une partie de la jointure
    donc, si tu n'as pas de correspondances CR.NUM_LIG_TOUR = L.NUM_LIG_TOUR, le champs L.NUM_LIG_TOUR sera null et ne sera pas visible car CR.NUM_TOUR = L.NUM_TOUR est obligatoire !
    il faut ouvrir toutes les jointures entre les tables

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    where CR.NUM_LIG_TOUR = L.NUM_LIG_TOUR(+) 
    and CR.NUM_TOUR       = L.NUM_TOUR (+)
    Idem pour les restrictions !

    De même tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    and CR.NUM_ART         = C.NUM_ART(+) 
    [...]
    and CR.NUM_CONT      = C.NUM_CONT
    C'est pas possible ! ou cela signifie que l'article (num_art) n'est pas tjs référencé mais que le contenu l'est toujours ?!!??


    Le mieux serait d'avoir un extrait de tes données, avec des create table et insert (avec tous les cas possible), ensuite tu donnes le résultat que tu souahites avoir, là on pourra t'aider, mais sans connaitre les tenants et juste une partie des aboutissant c'est pas evident.

    Contruit un exemple, que je peux lancer dans ma base, et détaille moi les différents cas.. là je pourrais t'aider

  5. #5
    Membre actif

    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 87
    Points : 281
    Points
    281
    Par défaut
    voici mes tables :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
        LIG_TOUR                  CR_STOCK                  CONTENANT
        ------------------          ----------------               ---------------
    ->  NUM_LIG_TOUR<--------->NUM_LIG_TOUR    
    |    NUM_TOUR   <---------->NUM_TOUR
    |                                     (NUM_ART)   <------>  NUM_ART
    |                                    NUM_CONT    <-------->NUM_CONT   
    |                                                               NUM_LIG_TOUR_INV <-
    ------------------------------------------------------------------------------------|
    les flèches représentent les jointures, et le champ entre parenthèses est "facultatif", c'est à dire qu'ils peut être null.

    de plus, si je n'ai pas de ligne de CR_STOCK, je dois afficher mes champs de LIG_TOUR et CONTENANT.
    si ma ligne de CR_STOCK existe et que j'ai un NUM_ART null, je dois tout de même prendre la ligne de CR_STOCK.

    pour l'instant j'ai cette requete-ci

    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
    create or replace view F_GESTOURINV_ACON as
    select L.NUM_TOUR			,
    	 L.NUM_LIG_TOUR		,
    	 C.EMP			EMP,
    	 C.NUM_CONT			NUM_CONT,
    	 C.NUM_ART			NUM_ART,
    	 C.NUM_LOT			NUM_LOT,
    	 C.DLUO			DLUO
      from LIG_TOUR L, CONTENANT C, CR_STOCK CR
     where CR.NUM_LIG_TOUR		= L.NUM_LIG_TOUR
       and CR.NUM_TOUR		= L.NUM_TOUR
       and (CR.NUM_ART		= C.NUM_ART
    	 or CR.NUM_ART is null)
       and CR.NUM_CONT		= C.NUM_CONT
       and L.NUM_LIG_TOUR		= C.NUM_LIG_TOUR_INV
       and L.TYP_TOUR			= 'INV'
       and L.TYP_REAL			= 'PAPI'
       and L.STYP_TOUR		= 'ACON'
       and L.ETAT_LIG_TOUR		= 'LANC'
       and CR.ETAT_CR_STOCK		!= 'TERM';
    qu'en penses-tu?

  6. #6
    Membre averti

    Inscrit en
    Septembre 2003
    Messages
    425
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 425
    Points : 398
    Points
    398
    Par défaut
    Super je me penche dessus.
    juste une question :
    si CR_STOCK.num_art est null, est ce que CONTENANT.num_art est null aussi ?

  7. #7
    Membre averti

    Inscrit en
    Septembre 2003
    Messages
    425
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 425
    Points : 398
    Points
    398
    Par défaut
    Ah si je comprends tu souahites les LIG_TOUR et les CONTENU, mais si il y a un CR_STOCK tu ne souahites pas l'avoir avec un etat TERM ?

    essai ca :
    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
     
    select L.NUM_TOUR         , 
           L.NUM_LIG_TOUR      , 
           C.EMP         EMP, 
           C.NUM_CONT         NUM_CONT, 
           C.NUM_ART         NUM_ART, 
           C.NUM_LOT         NUM_LOT, 
           C.DLUO         DLUO 
      from LIG_TOUR L, CONTENANT C
      where L.num_lig_tour = C.num_ligne_tour_inv
       and L.TYP_TOUR         = 'INV' 
       and L.TYP_REAL         = 'PAPI' 
       and L.STYP_TOUR      = 'ACON' 
       and L.ETAT_LIG_TOUR      = 'LANC' 
      and not exists (select null from cr_stock cr
                      where cr.num_lig_tour = l.num_lig_tour
                        and cr.NUM_TOUR = l.NUM_TOUR
                        and cr.ETAT_CR_STOCK = 'TERM')

  8. #8
    Membre actif

    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 87
    Points : 281
    Points
    281
    Par défaut
    Citation Envoyé par sygale
    Ah si je comprends tu souahites les LIG_TOUR et les CONTENU, mais si il y a un CR_STOCK tu ne souahites pas l'avoir avec un etat TERM ?
    c'est exactement ça.

    Citation Envoyé par sygale
    juste une question :
    si CR_STOCK.num_art est null, est ce que CONTENANT.num_art est null aussi ?
    non justement. CONTENANT.num_art peut être renseigné alors que CR_STOCK.num_art ne l'est pas.

    je sais que cela peut paraître incohérent mais je travaille sur qqchose d'existant, et je dois par conséquent m'adapter, c'est à dire faire avec ce que j'ai
    de même pour le fait qu'il y ait une boucle au niveau des jointures comme tu le disais précédemment. j'ai essayé de voir s'il m'était possible d'éviter cette boucle, mais vu le manque de cohérence au niveau des données, je ne crois pas pouvoir éviter cette boucle

    je teste ta requête demain matin.
    merci beaucoup pour ton aide, et à demain peut-être

  9. #9
    Membre actif

    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 87
    Points : 281
    Points
    281
    Par défaut
    ta requête fonctionne du tonnerre
    un grand merci à toi.

    cependant, j'aimerais faire la requête avec une jointure externe (sans sous-requête) afin d'optimiser les calculs..

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

Discussions similaires

  1. Requête avec jointures externes
    Par developpeur71 dans le forum Langage SQL
    Réponses: 13
    Dernier message: 18/06/2010, 13h03
  2. Requête avec jointure externe
    Par Neuromancien2 dans le forum Requêtes
    Réponses: 4
    Dernier message: 15/04/2008, 00h47
  3. Requête avec jointure externe complexe
    Par dpin33 dans le forum Langage SQL
    Réponses: 7
    Dernier message: 04/03/2008, 13h41
  4. optimisation requête avec jointures externes
    Par beurtom dans le forum Oracle
    Réponses: 14
    Dernier message: 16/10/2006, 16h50
  5. Requête avec jointure externe
    Par claralavraie dans le forum Langage SQL
    Réponses: 8
    Dernier message: 02/02/2006, 08h34

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