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 :

Rupture de jointure entre deux tables dans une requête


Sujet :

SQL Oracle

  1. #1
    Débutant
    Inscrit en
    Avril 2005
    Messages
    469
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 469
    Points : 106
    Points
    106
    Par défaut Rupture de jointure entre deux tables dans une requête
    Bonjour je dois effectuer une jointure entre deux tables pour qu'une fois la jointure faiite sur trois colonnes en respectant des conditions sur l'une des tables, ça m'améne des données de l'autre table sur une jointure de deux colonnes seulement.

    Exemple:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    TA
     
    col1               col2         col3               col4
    1                   2              3                 4
    5                   6              7                 8
    9                  10              11               12
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    TB
     
    col5       col6           col7               col8
    1            2              3                  8547  
    1            2              6                  9632
    1            2              0                  3696
    Maintenant je souhaite quand la jointue est faite sur les trois premieres colonnes des deux tables, aprés que ça puisse se jouer sur seulement les deux colonnes.
    exemple une requête qui me sortira seule la premiére ligne dela table A selon une condition définie :
    aprés les autres lignes doivent sortir les autres lignes de la table B pour lesquelles la jointure satisfasse les deux premiéres colonnes.



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    col1    col2        (col3 ou col7)       col8                     col4
     1        2            3                8547                        4
                           6                9632
                           0                3696
    Ici la requête ne doit ramner que la premiére ligne de la table A., c'est pour ça j'ai mis col3 ou col7 car aprés c'est col7 pour la deuxiéme table à savoir TB qui doit venir.

    Quel type de jointure je dois mettre en place pour réaliser ça ?
    merci de vos aides .

  2. #2
    Membre du Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2010
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Nord (Nord Pas de Calais)

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

    Informations forums :
    Inscription : Août 2010
    Messages : 44
    Points : 69
    Points
    69
    Par défaut
    Bonjour,

    Maintenant je souhaite quand la jointue est faite sur les trois premieres colonnes des deux tables, aprés que ça puisse se jouer sur seulement les deux colonnes.
    Cela ressemble fort à une jointure externe de TB vers TA sur les trois premières colonnes des deux tables.

    aprés les autres lignes doivent sortir les autres lignes de la table B pour lesquelles la jointure satisfasse les deux premiéres colonnes.
    à quoi il faudrait ajouter une restriction sur TB, stipulant qu'on ne doit sortir que les lignes pour lesquelles on trouve au moins une correspondance dans TA sur les deux premières colonnes :

    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
           TA.col1
          ,TA.col2
          ,TB.col7
          ,TB.col8
          ,TA.col4
      from TB
           LEFT OUTER JOIN TA
                        ON     TA.col1 = TB.col5
                           AND TA.col2 = TB.col6
                           AND TA.col3 = TB.col7
     where exists (select 1
                     FROM TA
                    where
                          TA.col1 = TB.col5
                      AND TA.col2 = TB.col6)
    C'est bien ça ?

    Cdlt,
    OD

  3. #3
    Débutant
    Inscrit en
    Avril 2005
    Messages
    469
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 469
    Points : 106
    Points
    106
    Par défaut
    Oui c'est bien ça mais quand je veux des conditions sur la Table A , je peux l'adjoindre dans le WHERE avec un and ?

  4. #4
    Débutant
    Inscrit en
    Avril 2005
    Messages
    469
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 469
    Points : 106
    Points
    106
    Par défaut
    En fait, ce que je veux c'est que lorsqu'il n'arrive plus à ramener des lignes pour la table TA avec les conditions définies, que ça raméne les lignes provenant de la table TB pour lesquelle ils ont sur deux colonnes en commun maintenant(jointures sur deux colonnes eu leiu de trois).

    voilà

    la requête d'en haut ça raméne que quand ils ont les trois colonnes en commun.

  5. #5
    Membre du Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2010
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Nord (Nord Pas de Calais)

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

    Informations forums :
    Inscription : Août 2010
    Messages : 44
    Points : 69
    Points
    69
    Par défaut
    Bonsoir,

    Je le mettrais dans la clause ON. Par exemple :
    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
           TA.col1
          ,TA.col2
          ,TB.col7
          ,TB.col8
          ,TA.col4
      FROM TB
           LEFT OUTER JOIN TA
                        ON     TA.col1 = TB.col5
                           AND TA.col2 = TB.col6
                           AND TA.col3 = TB.col7
                           AND TA.col4 = 4
     WHERE EXISTS (SELECT 1
                     FROM TA
                    WHERE
                          TA.col1 = TB.col5
                      AND TA.col2 = TB.col6)
    Cdlt,
    OD

  6. #6
    Débutant
    Inscrit en
    Avril 2005
    Messages
    469
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 469
    Points : 106
    Points
    106
    Par défaut
    D'accord je vois bien Olivier mais quand la condition doit porter aussi non pas seulement sur un colonne de la table TA mais sur d'autres colonnes d'autres tables qui seron en jointures simples avec TA, je me demande si je dois le placer aprés le On ou à l'intérieur de exists().

    Je m'explique si on doit avoir au niveau du SELECT prncipal d'autres colonnes provenant d'autres tables comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    select TC.col9, TD.col10 , TA.col9,Ta.col10
    et ces colonnes seront intervenues au niveau des conditons sur la table TA dont je vous parlais comme genre :
    TA.col9=TC.col9
    and TD.col10=TA.col10

    Donc ces conditions de jointures qui portent sur d'autres colonnes autres que celles de la table TB, on va les placer aprés le ON du LEFT ou dans l'autres SELECT de exists ?
    Et aussi la liste des autres tables on les mets sur quelle partie des SELECT ?

    Cordialement.
    madina

  7. #7
    Membre du Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2010
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Nord (Nord Pas de Calais)

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

    Informations forums :
    Inscription : Août 2010
    Messages : 44
    Points : 69
    Points
    69
    Par défaut
    Bonsoir,

    Vous pourrez alors passer par une vue virtuelle (clause WITH) :
    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
     
    WITH V_TA AS
    (
     SELECT
            TA.col1
           ,TA.col2
           ,TA.col3
           ,TA.col4
           ,TC.col9
           ,TD.col10
       FROM TA
            INNER JOIN TC ON TC.col9 = TA.col9
            INNER JOIN TD ON TD.col10 = TA.col10
      WHERE TA.col4 = 4 
    )
    SELECT
           V_TA.col1
          ,V_TA.col2
          ,TB.col7
          ,TB.col8
          ,V_TA.col4
          ,V_TA.col9
          ,V_TA.col10
      FROM TB
           LEFT OUTER JOIN V_TA
                        ON     V_TA.col1 = TB.col5
                           AND V_TA.col2 = TB.col6
                           AND V_TA.col3 = TB.col7
     WHERE EXISTS (SELECT 1
                     FROM V_TA V_TA2
                    WHERE
                          V_TA2.col1 = TB.col5
                      AND V_TA2.col2 = TB.col6)
    Explication :

    La clause WITH construit la vue virtuelle V_TA avec TA, TC et TD et toutes les clauses qui vont bien.

    La requête principale utilise cette vue virtuelle pour la jointure externe et la semi-jointure (V_TA2).


    Attention: la clause WITH ne fonctionne qu'à partir de Oracle version 9.

    Cdlt,
    OD

  8. #8
    Débutant
    Inscrit en
    Avril 2005
    Messages
    469
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 469
    Points : 106
    Points
    106
    Par défaut
    D'accord je vois bien.

    En fait pour la version j'ai bien une base de données Oracle Database 10g enterprise Edition mais la requête je l'utilise sous Oracle Report 6i.
    Et quand je le mets, il me signale l'erreur : instruction select absente.

    Je pensais qu'avec la version Database, ça devrait passer mais non.

    Merci quand même Oilvier d'avoir bien penché sur mon cas. , je vais devoir chercher une autre solution.

    Cordialement madina.

  9. #9
    Membre du Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2010
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Nord (Nord Pas de Calais)

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

    Informations forums :
    Inscription : Août 2010
    Messages : 44
    Points : 69
    Points
    69
    Par défaut
    Bonjour,


    Dans ce cas, sans passer par une clause WITH (inconnue dans Reports, la version de Oracle SQL étant inférieure), c'est un peu plus lourd, vous êtes obligé de dupliquer :

    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
    SELECT
           V_TA1.col1
          ,V_TA1.col2
          ,TB.col7
          ,TB.col8
          ,V_TA1.col4
          ,V_TA1.col9
          ,V_TA1.col10
      FROM TB
           LEFT OUTER JOIN (
                            SELECT
                                   TA.col1
                                  ,TA.col2
                                  ,TA.col3
                                  ,TA.col4
                                  ,TC.col9
                                  ,TD.col10
                              FROM TA
                                   INNER JOIN TC ON TC.col9 = TA.col9
                                   INNER JOIN TD ON TD.col10 = TA.col10
                             WHERE TA.col4 = 4 
                           ) V_TA1
                        ON     V_TA1.col1 = TB.col5
                           AND V_TA1.col2 = TB.col6
                           AND V_TA1.col3 = TB.col7
     WHERE EXISTS (SELECT 1
                     FROM (
                           SELECT
                                  TA.col1
                                 ,TA.col2
                                 ,TA.col3
                                 ,TA.col4
                                 ,TC.col9
                                 ,TD.col10
                             FROM TA
                                  INNER JOIN TC ON TC.col9 = TA.col9
                                  INNER JOIN TD ON TD.col10 = TA.col10
                            WHERE TA.col4 = 4 
                          ) V_TA2
                    WHERE
                          V_TA2.col1 = TB.col5
                      AND V_TA2.col2 = TB.col6)
    Mais cela fonctionnera sous Reports.

    Cdlt,
    OD

  10. #10
    Débutant
    Inscrit en
    Avril 2005
    Messages
    469
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 469
    Points : 106
    Points
    106
    Par défaut
    En fait là, je vois que c'est vraiment trop lourd.
    En effet pour la première solution, pourtant avec ça j'obtiens toutes les lignes de la table TB même si certaines d'entre elles ne sont pas présentes dans TA( la jointure externe marche bien).

    Mais le probléme le champ TA.col2 se répète autant de fois qu'il en a dans TB, y'a pas un moyen que je le groupe sur la requê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
    SELECT
           TA.col1
          ,TA.col2
          ,TB.col7
          ,TB.col8
          ,TA.col4
    FROM    TC , TD , TB LEFT OUTER JOIN TA on 
                          TA.col1 = TB.col5
                      AND TA.col2 = TB.col6
     
    WHERE   TA.col1= TD.col1 and   TC.col10 = TC.col10
                               WHERE TA.col4 = 4
    and EXISTS (SELECT 1
                     FROM TA
                    WHERE
                         TA.col1 = TB.col5
                           AND TA.col2 = TB.col6
                           AND TA.col3 = TB.col7)

  11. #11
    Membre du Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2010
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Nord (Nord Pas de Calais)

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

    Informations forums :
    Inscription : Août 2010
    Messages : 44
    Points : 69
    Points
    69
    Par défaut
    Bonsoir,

    Dans ce cas, je vous propose de nous passer de la jointure externe en construisant notre requête en deux parties distinctes.

    Requete 1 : on sort les lignes communes entre TA et TB, jointure interne donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    SELECT
           TA.col1
          ,TA.col2
          ,TB.col7
          ,TB.col8
          ,TA.col4
      FROM TB
           INNER JOIN TA
                        ON     TA.col1 = TB.col5
                           AND TA.col2 = TB.col6
                           AND TA.col3 = TB.col7
                           AND TA.col4 = 4
    Requete 2 : on sort les lignes de TB qui existent dans TA suivant les colonnes 1 et 2, mais sans les lignes communes (celles de la requête 1)
    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
           TB.  col7
          ,TB.  col8
      FROM TB
     WHERE EXISTS (SELECT 1
                     FROM TA
                    WHERE
                          TA.col1 = TB.col5
                      AND TA.col2 = TB.col6)
       AND NOT EXISTS
                  (SELECT 1
                     FROM TA
                    WHERE TA.col1 = TB.col5
                      AND TA.col2 = TB.col6
                      AND TA.col3 = TB.col7
                      AND TA.col4 = 4
                  )
    Enfin, on unifie le résultat des requêtes 1 et 2, en complétant la requête 2 pour que les colonnes des deux requêtes soient en phase :
    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
     
    SELECT
           TA.col1
          ,TA.col2
          ,TB.col7
          ,TB.col8
          ,TA.col4
      FROM TB
           INNER JOIN TA
                        ON     TA.col1 = TB.col5
                           AND TA.col2 = TB.col6
                           AND TA.col3 = TB.col7
                           AND TA.col4 = 4
    UNION ALL
    SELECT
           null col1
          ,null col2
          ,TB.  col7
          ,TB.  col8
          ,null col4
      FROM TB
     WHERE EXISTS (SELECT 1
                     FROM TA
                    WHERE
                          TA.col1 = TB.col5
                      AND TA.col2 = TB.col6)
       AND NOT EXISTS
                  (SELECT 1
                     FROM TA
                    WHERE TA.col1 = TB.col5
                      AND TA.col2 = TB.col6
                      AND TA.col3 = TB.col7
                      AND TA.col4 = 4
                  )
    Pour les tables TC et TD, je vous laisse compléter.

    Remarque : il est possible que les "null" tout seul ne passent pas. Il vous faudra alors les "typer" : to_char(null), to_date(null), to_number(null)

    Cdlt,
    OD

  12. #12
    Débutant
    Inscrit en
    Avril 2005
    Messages
    469
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 469
    Points : 106
    Points
    106
    Par défaut
    D'accord Olivier je vois.
    Mais le probléme est que comme je suis sous Report, les 3 requêtes dans le même Data Model risquent de me poser des problèmes ou se perdre.
    En fait moi mon probléme c'était seulement comment grouper la colonne qui s e répétait sur les lignes pour les mêmes valeurs sans à intervenir au niveau de la présentation.

    ça rentre dans le cadre du report je crois.

    Merci vraiment d'avoir pris du temps pour mon cas.

    Cordialement

Discussions similaires

  1. [MySQL] Faire une jointure entre deux tables qui ne sont pas dans la même base de données
    Par sandddy dans le forum PHP & Base de données
    Réponses: 12
    Dernier message: 03/04/2008, 14h18
  2. Jointure entre deux champs d'une même table
    Par oubli dans le forum Requêtes
    Réponses: 8
    Dernier message: 11/12/2007, 16h20
  3. recherche entre deux dates dans une requête
    Par emmanuel4945 dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 29/11/2006, 21h42
  4. calcul entre deux champs dans une table
    Par pomar dans le forum Access
    Réponses: 7
    Dernier message: 29/11/2006, 18h27
  5. Comparaison entre deux dates dans une table
    Par Biskot75 dans le forum Access
    Réponses: 6
    Dernier message: 19/09/2006, 11h16

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