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 :

[PostGre SQL] Jointure multiples impossible


Sujet :

Langage SQL

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 61
    Points : 71
    Points
    71
    Par défaut [PostGre SQL] Jointure multiples impossible
    Bonjour je me fais jeter par ma DB (en l'occurence pggsql) car on ne peu pas exprimer une jointure gauche d'une table t1 sur les tables t2,t3, t4 et ensuite poser une autre jointure gauche (ou full) de de t3 sur t5.

    Dans le cas qui m'occupe ça 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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    SELECT 
    collaborateurs.col_id,
    collaborateurs.col_matricule,
    collaborateurs.col_nom,
    collaborateurs.col_prenom,
    collaborateurs.col_dt_entree, 
    collaborateurs.col_qual,
    collaborateurs.col_formation,
    collaborateurs.ser_id, 
    collaborateurs.ag_id,
    collaborateurs.col_typeimport, 
    collaborateurs.col_dt_naiss, 
    collaborateurs.col_int_ext, 
    collaborateurs.col_sexe, 
    collaborateurs.col_nomabrege, 
    collaborateurs.col_diplome, 
    collaborateurs.col_pr_semicomplet,
    collaborateurs.col_pr_complet,
    metiers.met_id,
    metiers.met_lib,
    li_col_fct.fct_id,
    fonction.fct_lib, 
    ct.ct_id, 
    ct.ct_lib, 
    lmtc.ct_valide,
    tc.typ_id, 
    tc.typ_lib, 
    lccf.notfct_val,
    service.ser_lib
    FROM
    collaborateurs  LEFT   OUTER JOIN li_col_met ON (collaborateurs.col_id = li_col_met.col_id)
    LEFT  OUTER JOIN li_col_fct  ON (collaborateurs.col_id = li_col_fct.col_id)
    LEFT   OUTER JOIN service  ON (collaborateurs.ser_id = service.ser_id),
    competences_tech ct, 
    type_ct tc,
    li_col_ct_fct lccf,
    li_col_met LEFT  OUTER JOIN metiers ON (li_col_met.met_id = metiers.met_id),
    li_col_fct LEFT  OUTER JOIN fonction  ON (li_col_fct.fct_id = fonction.fct_id),
    li_met_typ_ct lmtc
    D'un point de vue logique, 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
     
    SELECT 
    (...)
    FROM
    t1  FULL   OUTER JOIN t2 ON (...)
    LEFT  OUTER JOIN t3  ON (...)
    LEFT   OUTER JOIN t4  ON (...),
    t5, 
    t6,
    t7,
    t2 LEFT  OUTER JOIN t8 ON (...),
    t3 LEFT   OUTER JOIN t9  ON (...),
    t10;
    Comment, puis-je d'un point de vue logique pallier à ce problème ?

  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 772
    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 772
    Points : 52 737
    Points
    52 737
    Billets dans le blog
    5
    Par défaut
    je ne voit aucune de vos jointures Interne... Si vous les faîtes dans le where c'est de cela que vient votre connerie.

    Soit vous en restez à l'ancienne syntaxe qui date d'avant 1992... Soit vous mettez des INNER JOIN et des OUTER JOIN. Mais un mélange des deux est incompréhensible pour un parseur SQL !

    A +
    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
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 61
    Points : 71
    Points
    71
    Par défaut
    Citation Envoyé par SQLpro
    je ne voit aucune de vos jointures Interne... Si vous les faîtes dans le where c'est de cela que vient votre connerie.

    Soit vous en restez à l'ancienne syntaxe qui date d'avant 1992... Soit vous mettez des INNER JOIN et des OUTER JOIN. Mais un mélange des deux est incompréhensible pour un parseur SQL !

    A +
    Je ne peux et ne veut rester à l'ancienne syntaxe vu que le sgbd (il s'agit d'une migration) est SQL92 (pgsql), il me semble.

    A l'origine, j'ai cela :

    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
    select a.*,
           b.met_id,b.met_lib,
           h.fct_id,
           c.fct_lib,
           d.ct_id,d.ct_lib,j.ct_valide,
           e.typ_id,e.typ_lib,
           f.notfct_val,
           i.ser_lib  
    from 
        collaborateurs a,
        metiers b,
        fonction c,
        competences_tech d,
        type_ct e,
        li_col_ct_fct f,
        li_col_met g,
        li_col_fct h,
        service i,
        LI_MET_TYP_CT j
    where 
        (a.col_id=g.col_id(+) 
        and g.met_id=b.met_id(+)) 
        and (a.col_id=h.col_id(+) 
        and h.fct_id=c.fct_id(+)) 
        and (f.col_id=a.col_id and f.met_id=b.met_id and d.ct_id=f.ct_id) 
        and (j.typ_id=e.typ_id) 
        and (a.ser_id = i.ser_id(+)) 
        and (j.ct_id = d.ct_id)
        and (j.met_id = g.met_id)
    Si j'ai bien compris (c'est comme ça que j'ai réécri ma requête)

    dans le where

    deviendrait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    g left outer join a on (a.col_id=g.col_id)
    ?

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 61
    Points : 71
    Points
    71
    Par défaut

    dans le where

    deviendrait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    g left outer join a on (a.col_id=g.col_id)
    ?
    Non c'est l'inverse
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    a left outer join g on (a.col_id=g.col_id)

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 61
    Points : 71
    Points
    71
    Par défaut Repartons ds le début.
    J'ai pris le parti de recommencer à transformer le code

    je part donc de (format oracle) :
    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
    select a.*,
           b.met_id,b.met_lib,
           h.fct_id,
           c.fct_lib,
           d.ct_id,d.ct_lib,j.ct_valide,
           e.typ_id,e.typ_lib,
           f.notfct_val,
           i.ser_lib  
    from 
        collaborateurs a,
        metiers b,
        fonction c,
        competences_tech d,
        type_ct e,
        li_col_ct_fct f,
        li_col_met g,
        li_col_fct h,
        service i,
        LI_MET_TYP_CT j
    where 
        (a.col_id=g.col_id(+) 
        and g.met_id=b.met_id(+)) 
        and (a.col_id=h.col_id(+) 
        and h.fct_id=c.fct_id(+)) 
        and (f.col_id=a.col_id and f.met_id=b.met_id and d.ct_id=f.ct_id) 
        and (j.typ_id=e.typ_id) 
        and (a.ser_id = i.ser_id(+)) 
        and (j.ct_id = d.ct_id)
        and (j.met_id = g.met_id)
    order by a.col_nom asc , c.fct_lib asc , e.typ_lib asc , j.ct_valide desc, d.ct_lib asc;
    à
    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 collaborateurs.*,
           metiers.met_id,metiers.met_lib,
               li_col_fc.fct_id,
           fonction.fct_lib,
           competences_tech.ct_id,competences_tech.ct_lib,
        LI_MET_TYP_CT.ct_valide,
           type_ct.typ_id,type_ct.typ_lib,
           li_col_ct_fct.notfct_val,
           service.ser_lib  
    from 
    --    collaborateurs,
    --    metiers ,
    --    fonction ,
        competences_tech ,
        type_ct ,
        li_col_ct_fct ,
    --    li_col_met ,
    --    li_col_fct ,
     
        LI_MET_TYP_CT,
     
        collaborateurs left outer join li_col_met on (collaborateurs.col_id=li_col_met.col_id)
        left outer join li_col_fct on (collaborateurs.col_id=li_col_fct.col_id)
        left outer join service on (collaborateurs.ser_id = service.ser_id),
        li_col_fct left outer join fonction on     (li_col_fct.fct_id=fonction.fct_id),
        li_col_met left outer join metiers on (li_col_met.met_id=metiers.met_id)
    where
    --     li_col_met.met_id=metiers.met_id(+)) 
     LI_MET_TYP_CT.typ_id=type_ct.typ_id
    --    and (collaborateurs.col_id=li_col_fc.col_id(+) 
    --    and     li_col_fc.fct_id=fonction.fct_id(+)) 
        and (li_col_ct_fct.col_id=collaborateurs.col_id and li_col_ct_fct.met_id=metiers.met_id and competences_tech.ct_id=li_col_ct_fct.ct_id) and
         (LI_MET_TYP_CT.typ_id=type_ct.typ_id) 
    --    and (collaborateurs.ser_id = service.ser_id(+)) 
        and (LI_MET_TYP_CT.ct_id = competences_tech.ct_id)
        and (LI_MET_TYP_CT.met_id = li_col_met.met_id)
    order by collaborateurs.col_nom asc , fonction.fct_lib asc , type_ct.typ_lib asc , LI_MET_TYP_CT.ct_valide desc, competences_tech.ct_lib asc;
    J'ai volontairement laissé en commentaires certaines lignes pour la clarté (il s'agit des lignes ayant été réécrites).

    Le problème c'est que Pgsql (et tout autre SGBD sql92 et +) me crache :
    "ERROR: table name "li_col_fct" specified more than once"

    Ce qui est effectivement vrai car j'utilise la table li_col_fct comme table droite d'une première jointure, puis comme table gauche d'une autre jointure.

    Comment puis je me sortir de ce mauvais pas ?

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 61
    Points : 71
    Points
    71
    Par défaut
    Citation Envoyé par SQLpro
    je ne voit aucune de vos jointures Interne... Si vous les faîtes dans le where c'est de cela que vient votre connerie.

    Soit vous en restez à l'ancienne syntaxe qui date d'avant 1992... Soit vous mettez des INNER JOIN et des OUTER JOIN. Mais un mélange des deux est incompréhensible pour un parseur SQL !

    A +
    Je suis désolé, mais je comprend pas vraiment le sens de ce vous dites...

    Il n' y a pas de clauses where dans mon code.
    Il n' y a que des OUTER JOIN....

    Enfin je vois pas...

  7. #7
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    Sans les create table ni jeu d'essai je n'ai pas pu vérifier :

    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 a.*,
           b.met_id,b.met_lib,
           h.fct_id,
           c.fct_lib,
           d.ct_id,d.ct_lib,j.ct_valide,
           e.typ_id,e.typ_lib,
           f.notfct_val,
           i.ser_lib  
    from collaborateurs a inner join li_col_ct_fct f    on f.col_id = a.col_id
                          inner join competences_tech d on d.ct_id  = f.ct_id
                          inner join LI_MET_TYP_CT j    on j.ct_id  = d.ct_id
                          inner join type_ct e          on j.typ_id = e.typ_id
                          left  join li_col_met g       on a.col_id = g.col_id
                                                       and j.met_id = g.met_id
                          left  join metiers b          on g.met_id = b.met_id
                                                       and f.met_id = b.met_id
                          left  join li_col_fct h       on a.col_id = h.col_id
                          left  join fonction c         on h.fct_id = c.fct_id
                          left  join service i          on a.ser_id = i.ser_id
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 61
    Points : 71
    Points
    71
    Par défaut
    Citation Envoyé par Médiat
    Sans les create table ni jeu d'essai je n'ai pas pu vérifier :

    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 a.*,
           b.met_id,b.met_lib,
           h.fct_id,
           c.fct_lib,
           d.ct_id,d.ct_lib,j.ct_valide,
           e.typ_id,e.typ_lib,
           f.notfct_val,
           i.ser_lib  
    from collaborateurs a inner join li_col_ct_fct f    on f.col_id = a.col_id
                          inner join competences_tech d on d.ct_id  = f.ct_id
                          inner join LI_MET_TYP_CT j    on j.ct_id  = d.ct_id
                          inner join type_ct e          on j.typ_id = e.typ_id
                          left  join li_col_met g       on a.col_id = g.col_id
                                                       and j.met_id = g.met_id
                          left  join metiers b          on g.met_id = b.met_id
                                                       and f.met_id = b.met_id
                          left  join li_col_fct h       on a.col_id = h.col_id
                          left  join fonction c         on h.fct_id = c.fct_id
                          left  join service i          on a.ser_id = i.ser_id
    Merci !

    Elle marche presque : elle sort de fois plus de donnée que l'original, mais j'ai enfin une matière sur laquelle travailler.

  9. #9
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 772
    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 772
    Points : 52 737
    Points
    52 737
    Billets dans le blog
    5
    Par défaut
    VOUS NE DEVEZ PAS MELANGER DES JOINTURES FAITES DANS LA CLAUSE WHERE AVEC DES JOINTURES FAITES AVEC LE PREDICAT JOIN.

    DONC TOUTES VOS JOINTURES DOIVENT ÊTRE INTODUITES AVEC JOIN... ON ...

    INNER JOIN
    LETF OUTER JOIN
    RIGHT OUTER JOIN
    FULL OUTER JOIN
    CROSS JOIN
    UNION JOIN
    NATURAL INNER JOIN
    NATURAL LETF OUTER JOIN
    NATURAL RIGHT OUTER JOIN
    NATURAL FULL OUTER JOIN

    EST-CE PLUS CLAIR ?

    SI cela ne l'est pas, lisez l'article que j'ai écrit à ce sujet :
    http://sqlpro.developpez.com/cours/sqlaz/jointures/


    A +
    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/ * * * * *

Discussions similaires

  1. [2008R2] Jointures multiples en SQL
    Par kennely dans le forum Développement
    Réponses: 17
    Dernier message: 24/09/2014, 17h25
  2. Requête SQL avec multiples jointures
    Par CedriZero dans le forum Requêtes
    Réponses: 2
    Dernier message: 16/01/2014, 15h29
  3. Requete SQL avec jointure multiple
    Par kissskoool dans le forum Langage SQL
    Réponses: 5
    Dernier message: 20/01/2008, 01h07
  4. [SQL 2000] Optimisation requête avec jointure multiple
    Par zooffy dans le forum Développement
    Réponses: 5
    Dernier message: 18/09/2007, 15h38
  5. [SQL 2000] Optimisation requête avec jointure multiple
    Par zooffy dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 18/09/2007, 15h38

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