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

Langage SQL Discussion :

SQL Informix - Jointure externe


Sujet :

Langage SQL

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 45
    Points : 26
    Points
    26
    Par défaut SQL Informix - Jointure externe
    Bonjour,

    J'ai une question liée à l'utilisation des jointures externes, ici sous Informix (mais la question est globale).

    La table A2742 contient des lots de factures.
    La table A2741 contient des factures.
    Le lien entre les deux tables se fait par la clé primaire de la A2742 :
    -CMNELOTD_R
    -DTRTLOTD_R
    -NORDLOTD_R
    -NDPTCPUD_R

    On souhaite obtenir une liste de lots correspondant à des critères basés sur des rubriques de l’une ou l’autre table. En l’occurrence :
    -DTRTLOTD_R (A2742 et A2741)
    -CGRG_GES (A2741)
    -NETSGEO (A2741)
    -NDPT_GES (A2741)
    -DCRELOT (A2741)

    La requête ci-dessous est élaborée automatiquement à partir d’informations saisies dans un AGL :
    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
    SELECT DISTINCT                                                          
                  A2741.NP_JMAL,                                                   
                  A2741.CMNELOTD_R,                                                
                  A2741.DTRTLOTD_R,                                                
                  A2741.NORDLOTD_R,                                                
                  A2741.NDPTCPUD_R,                                                
                  A2741.CGRG_GES,                                                  
                  A2741.NDPT_GES,                                                  
                  A2741.NETSGEO,                                                   
                  A2741.NLOTPDS,                                                   
                  A2741.DCRELOT,                                                   
                  A2741.VSRL_A2741,                                                
                  A2742.CMNELOTD_R,                                                
                  A2742.DTRTLOTD_R,                                                
                  A2742.NORDLOTD_R,                                                
                  A2742.NDPTCPUD_R,                                                
                  A2742.NEMTNRT,                                                   
                  A2742.NDESNRT,                                                   
                  A2742.LNOMFICNRT,                                                
                  A2742.NLOTPDS,                                                   
                  A2742.DCRELOT,                                                   
                  A2742.CNRT_001,                                                  
                  A2742.NVERNOR,                                                   
                  A2742.VSRL_A2742                                                 
          FROM                                                                     
                  OUTER          A2741,                                            
                   A2742                                                           
          WHERE 1=1                                                                
                  AND A2742.CMNELOTD_R = A2741.CMNELOTD_R                          
                  AND A2742.DTRTLOTD_R = A2741.DTRTLOTD_R                          
                  AND A2742.NDPTCPUD_R = A2741.NDPTCPUD_R                          
                  AND A2742.NORDLOTD_R = A2741.NORDLOTD_R                          
                  AND A2741.NP_JMAL >= "A"                             
                  AND (A2742.NLOTPDS = 0                             
                   OR 0 =0)                                         
                  AND (A2741.NETSGEO = "03078015"                            
                   OR 0 = 1)                                         
                  AND (A2741.CGRG_GES = "02"                          
                   OR 0 = 1)                                        
                  AND (A2741.NDPT_GES = "046"                           
                   OR 0 = 1)                                        
                  AND (A2741.DTRTLOTD_R = "20080302"                       
                   OR 0 = 1)                                      
                  AND A2741.DCRELOT BETWEEN                                        
                  "20070903"                                               
                  AND "20071231"                                           
          ;
    N’obtenant pas ce que je souhaitais, j’ai réduit la requête à cette expression :

    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 DISTINCT
                    A2741.CMNELOTD_R,
                    A2741.DTRTLOTD_R,
                    A2741.NORDLOTD_R,
                    A2741.NDPTCPUD_R,
                    A2742.CMNELOTD_R,
                    A2742.DTRTLOTD_R,
                    A2742.NORDLOTD_R,
                    A2742.NDPTCPUD_R
    FROM
                         A2742,
                   OUTER A2741
    WHERE             A2741.CMNELOTD_R = A2742.CMNELOTD_R
                  AND A2741.DTRTLOTD_R = A2742.DTRTLOTD_R
                  AND A2741.NDPTCPUD_R = A2742.NDPTCPUD_R
                  AND A2741.NORDLOTD_R = A2742.NORDLOTD_R
          AND A2741.CMNELOTD_R = "DR"
          AND A2741.DTRTLOTD_R = "20080110"
          AND A2741.NORDLOTD_R = 1
          AND A2741.NDPTCPUD_R = "031"
          ;
    Le résultat apparaît ci-dessous : 92 lignes (il y a 92 lots distincts). Mais :
    -je ne demande qu’un seul lot
    -les données provenant de la table A2741 ne sont pas renseignées, sauf sur 1 enregistrement

    ;;;;DR;20080102;1;082;
    ;;;;DR;20080102;2;082;
    ;;;;DR;20080102;3;082;
    ;;;;DR;20080102;4;082;
    ;;;;DR;20080102;5;082;
    ;;;;DR;20080102;6;082;
    ;;;;DR;20080102;7;082;
    ;;;;DR;20080102;8;082;
    ;;;;DR;20080102;9;082;
    ;;;;DR;20080102;10;082;
    ;;;;DR;20080110;2;031;
    ;;;;DR;20080110;3;031;
    ;;;;DR;20080110;4;031;
    ;;;;DR;20080110;5;031;
    ;;;;DR;20080110;6;031;
    ;;;;DR;20080110;7;031;
    ;;;;DR;20080110;8;031;
    ;;;;DR;20080110;9;031;
    ;;;;DR;20080110;10;031;
    ;;;;DR;20080120;1;031;
    ;;;;DR;20080120;2;031;
    ;;;;DR;20080120;3;031;
    ;;;;DR;20080120;4;031;
    ;;;;DR;20080120;5;031;
    ;;;;DR;20080120;6;031;
    ;;;;DR;20080120;7;031;
    ;;;;DR;20080120;8;031;
    ;;;;DR;20080120;9;031;
    ;;;;DR;20080120;10;031;
    ;;;;DR;20080130;1;031;
    ;;;;DR;20080130;2;031;
    ;;;;DR;20080130;3;031;
    ;;;;DR;20080130;4;031;
    ;;;;DR;20080130;5;031;
    ;;;;DR;20080130;6;031;
    ;;;;DR;20080130;7;031;
    ;;;;DR;20080130;8;031;
    ;;;;DR;20080130;9;031;
    ;;;;DR;20080130;10;031;
    ;;;;DR;20080202;1;046;
    ;;;;DR;20080202;2;046;
    ;;;;DR;20080202;3;046;
    ;;;;DR;20080202;4;046;
    ;;;;DR;20080202;5;046;
    ;;;;DR;20080202;6;046;
    ;;;;DR;20080202;7;046;
    ;;;;DR;20080202;8;046;
    ;;;;DR;20080202;9;046;
    ;;;;DR;20080202;10;046;
    ;;;;DR;20080211;1;031;
    ;;;;DR;20080211;2;031;
    ;;;;DR;20080211;3;031;
    ;;;;DR;20080211;4;031;
    ;;;;DR;20080211;5;031;
    ;;;;DR;20080211;6;031;
    ;;;;DR;20080211;7;031;
    ;;;;DR;20080211;8;031;
    ;;;;DR;20080211;9;031;
    ;;;;DR;20080211;10;031;
    ;;;;DR;20080212;1;031;
    ;;;;DR;20080212;2;031;
    ;;;;DR;20080212;3;031;
    ;;;;DR;20080212;4;031;
    ;;;;DR;20080212;5;031;
    ;;;;DR;20080212;6;031;
    ;;;;DR;20080212;7;031;
    ;;;;DR;20080212;8;031;
    ;;;;DR;20080212;9;031;
    ;;;;DR;20080212;10;031;
    ;;;;DR;20080213;1;031;
    ;;;;DR;20080213;2;031;
    ;;;;DR;20080213;3;031;
    ;;;;DR;20080213;4;031;
    ;;;;DR;20080213;5;031;
    ;;;;DR;20080213;6;031;
    ;;;;DR;20080213;7;031;
    ;;;;DR;20080213;8;031;
    ;;;;DR;20080213;9;031;
    ;;;;DR;20080213;10;031;
    ;;;;DR;20080213;11;031;
    ;;;;DR;20080213;12;031;
    ;;;;DR;20080302;1;031;
    ;;;;DR;20080302;2;031;
    ;;;;DR;20080302;3;031;
    ;;;;DR;20080302;4;031;
    ;;;;DR;20080302;5;031;
    ;;;;DR;20080302;6;031;
    ;;;;DR;20080302;7;031;
    ;;;;DR;20080302;8;031;
    ;;;;DR;20080302;9;031;
    ;;;;DR;20080302;10;031;
    DR;20080110;1;031;DR;20080110;1;031;
    Si je modifie la requête pour inverser les rubriques sur lesquelles je fais la sélection :

    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 DISTINCT
                    A2741.CMNELOTD_R,
                    A2741.DTRTLOTD_R,
                    A2741.NORDLOTD_R,
                    A2741.NDPTCPUD_R,
                    A2742.CMNELOTD_R,
                    A2742.DTRTLOTD_R,
                    A2742.NORDLOTD_R,
                    A2742.NDPTCPUD_R
    FROM
                         A2742,
                   OUTER A2741
    WHERE             A2741.CMNELOTD_R = A2742.CMNELOTD_R
                  AND A2741.DTRTLOTD_R = A2742.DTRTLOTD_R
                  AND A2741.NDPTCPUD_R = A2742.NDPTCPUD_R
                  AND A2741.NORDLOTD_R = A2742.NORDLOTD_R
          AND A2742.CMNELOTD_R = "DR"
          AND A2742.DTRTLOTD_R = "20080110"
          AND A2742.NORDLOTD_R = 1
          AND A2742.NDPTCPUD_R = "031"
          ;
    J’obtiens le résultat suivant :
    DR;20080110;1;031;DR;20080110;1;031;
    TOUT A FAIT SATISFAISANT étant donné que je ne sélectionne qu’un seul lot.

    D’où ma question :
    - lors de la mise en place d’une jointure externe, doit-on systématiquement procéder à la sélection sur les rubriques de la table « dominante » ?
    Dans l’affirmative :
    - que doit-on faire lorsque les rubriques sur lesquelles doit porter la sélection ne sont présentes que dans la table « subordonnée » ?

    Je vous remercie par avance pour vos remarques, explications, réponses ...

    DVi
    Images attachées Images attachées

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 770
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 770
    Points : 52 726
    Points
    52 726
    Billets dans le blog
    5
    Par défaut
    Tout d'abord deux erreurs dans votre code :
    1) une jointure externe s'écrit LEFT, RIGHT ou FULL OUTER JOIN et un prédicat de jointure (ON). Lire l'article que j'ai écrit à ce sujet :
    http://sqlpro.developpez.com/cours/sqlaz/jointures/#L2
    2) les chaines de caractères s'entourent de guillemets, pas d'apostrophe !

    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
    SELECT DISTINCT
           A2741.CMNELOTD_R,
           A2741.DTRTLOTD_R,
           A2741.NORDLOTD_R,
           A2741.NDPTCPUD_R,
           A2742.CMNELOTD_R,
           A2742.DTRTLOTD_R,
           A2742.NORDLOTD_R,
           A2742.NDPTCPUD_R
    FROM   A2742
           LEFT OUTER JOIN A2741
                ON     A2741.CMNELOTD_R = A2742.CMNELOTD_R
                   AND A2741.DTRTLOTD_R = A2742.DTRTLOTD_R
                   AND A2741.NDPTCPUD_R = A2742.NDPTCPUD_R
                   AND A2741.NORDLOTD_R = A2742.NORDLOTD_R
    WHERE  AND A2741.CMNELOTD_R = 'DR'
           AND A2741.DTRTLOTD_R = '20080110'
           AND A2741.NORDLOTD_R = 1
           AND A2741.NDPTCPUD_R = '031';
    Maintenant pour vos question philosophiques, vous comprendrez la chose en intégrant le filtre dans la clause de jointure ou or la clause de jointure, voir en utilisant le IS NULL...

    Les 3 écritures suivantes vous donnerons 3 résultats différents :

    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
    -- jointure externe avec filtre strict
    SELECT DISTINCT
           A2741.CMNELOTD_R,
           A2741.DTRTLOTD_R,
           A2741.NORDLOTD_R,
           A2741.NDPTCPUD_R,
           A2742.CMNELOTD_R,
           A2742.DTRTLOTD_R,
           A2742.NORDLOTD_R,
           A2742.NDPTCPUD_R
    FROM   A2742
           LEFT OUTER JOIN A2741
                ON     A2742.CMNELOTD_R = A2741.CMNELOTD_R
                   AND A2742.DTRTLOTD_R = A2741.DTRTLOTD_R
                   AND A2742.NDPTCPUD_R = A2741.NDPTCPUD_R
                   AND A2742.NORDLOTD_R = A2741.NORDLOTD_R
    WHERE  AND A2741.CMNELOTD_R = 'DR'
           AND A2741.DTRTLOTD_R = '20080110'
           AND A2741.NORDLOTD_R = 1
           AND A2741.NDPTCPUD_R = '031';
     
    -- jointure externe avec filtre strict ou externe
    SELECT DISTINCT
           A2741.CMNELOTD_R,
           A2741.DTRTLOTD_R,
           A2741.NORDLOTD_R,
           A2741.NDPTCPUD_R,
           A2742.CMNELOTD_R,
           A2742.DTRTLOTD_R,
           A2742.NORDLOTD_R,
           A2742.NDPTCPUD_R
    FROM   A2742
           LEFT OUTER JOIN A2741
                ON     A2742.CMNELOTD_R = A2741.CMNELOTD_R
                   AND A2742.DTRTLOTD_R = A2741.DTRTLOTD_R
                   AND A2742.NDPTCPUD_R = A2741.NDPTCPUD_R
                   AND A2742.NORDLOTD_R = A2741.NORDLOTD_R
    WHERE  AND (A2741.CMNELOTD_R = 'DR'       OR A2741.CMNELOTD_R IS NULL)
           AND (A2741.DTRTLOTD_R = '20080110' OR A2741.DTRTLOTD_R IS NULL)
           AND (A2741.NORDLOTD_R = 1          OR A2741.NORDLOTD_R IS NULL)
           AND (A2741.NDPTCPUD_R = '031'      OR A2741.NDPTCPUD_R IS NULL)
     
     
    -- jointure externe avec filtre externe
    SELECT DISTINCT
           A2741.CMNELOTD_R,
           A2741.DTRTLOTD_R,
           A2741.NORDLOTD_R,
           A2741.NDPTCPUD_R,
           A2742.CMNELOTD_R,
           A2742.DTRTLOTD_R,
           A2742.NORDLOTD_R,
           A2742.NDPTCPUD_R
    FROM   A2742
           LEFT OUTER JOIN A2741
                ON     A2742.CMNELOTD_R = A2741.CMNELOTD_R
                   AND A2742.DTRTLOTD_R = A2741.DTRTLOTD_R
                   AND A2742.NDPTCPUD_R = A2741.NDPTCPUD_R
                   AND A2742.NORDLOTD_R = A2741.NORDLOTD_R
                   AND (A2741.CMNELOTD_R = 'DR'       OR A2741.CMNELOTD_R IS NULL)
                   AND (A2741.DTRTLOTD_R = '20080110' OR A2741.DTRTLOTD_R IS NULL)
                   AND (A2741.NORDLOTD_R = 1          OR A2741.NORDLOTD_R IS NULL)
                   AND (A2741.NDPTCPUD_R = '031'      OR A2741.NDPTCPUD_R IS NULL)

    Je laisse à votre sagacité le soin de les expliquer !

    A +

    Exemple :
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 45
    Points : 26
    Points
    26
    Par défaut
    Tout d'abord je vous remercie pour les éléments de réponse que vous m'avez transmis et auxquels je vais immédiatement m'intéresser.

    Une précision cependant : je suis "contraint" par un AGL qui génère les requêtes et qui utilise OUTER sans attribut particulier, LEFT étant, si mes souvenirs sont bons, pris par défaut.

    Me référant à la doc Informix en ma possession ("Informix Guide to SQL", v7.2), le requête peut être codée sans préciser la valeur LEFT (cf PJ).


    Concernant les guillemets qui entourent les critères de sélection, ils sont généralisés sur le site sur lequel je travaille actuellement, contrairement à ce que j'avais connu précédemment.

    Ceci étant dit, je vous renouvelle mes remerciements pour votre réponse. Je vais analyser les divers types de requêtes proposés ainsi que votre doc en ligne.
    Images attachées Images attachées  

Discussions similaires

  1. [MySQL] requête SQL de jointure externe
    Par makamine dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 18/05/2011, 12h10
  2. [SQL Server] jointure externe et SUM
    Par TangoZoulou dans le forum Langage SQL
    Réponses: 6
    Dernier message: 07/11/2006, 15h13
  3. [SQL] Jointure externe dans "les 2 sens"
    Par Bounty Killer dans le forum Oracle
    Réponses: 3
    Dernier message: 04/05/2006, 10h56
  4. [SQL] jointure externe
    Par Sniper37 dans le forum Langage SQL
    Réponses: 6
    Dernier message: 02/09/2005, 15h06
  5. [SQL] jointure externe avec 3 tables, comment faire ....
    Par grumbok dans le forum Langage SQL
    Réponses: 2
    Dernier message: 04/08/2005, 16h13

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