Requête sur trois tables [Résolu]

Messages postés
60
Date d'inscription
dimanche 7 novembre 2010
Statut
Membre
Dernière intervention
4 août 2012
- - Dernière réponse : tpoinsot
Messages postés
345
Date d'inscription
mardi 1 juin 2004
Statut
Membre
Dernière intervention
17 octobre 2014
- 15 févr. 2012 à 17:01
Bonjour,

J'ai une table contenant X qui à plusieurs colonnes dont CS_PERS_PRO. Cette table X se rattache à deux autres tables Y et Z.

exemple :

table X :

CS_PERS_PRO (nom colonne)
0125
0354
CTDS
RFBS

-----------------------------
table Y :

CodeCS (nom colonne)
0125
0354

-----------------------------
table Z :

CODE_SERVICE (nom colonne)
CTDS
RFBS


Je souhaite récupérer les libelles des tables Y et Z grace au CS_PERS_PRO en faisant deux jointures mais cela ne marche pas :

SELECT * FROM X WHERE X.CS_PERS_PRO Y.CodeCS AND X.CS_PERS_PRO Z.CODE_SERVICE

Comment puis-je faire ? merci pour vos réponses
Afficher la suite 

19 réponses

Meilleure réponse
Messages postés
219
Date d'inscription
mercredi 26 octobre 2011
Statut
Membre
Dernière intervention
22 juin 2017
8
3
Merci
Bonjour,

tu dois mettre tes trois tables dans la clause from

comme ceci

SELECT X.*,Y.*,Z.* FROM X,Y,Z WHERE X.CS_PERS_PRO Y.CodeCS AND X.CS_PERS_PRO Z.CODE_SERVICE 


Bonne journée



Faites simple, aussi simple que possible, mais pas simpliste.
A. Einstein.

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 197 internautes nous ont dit merci ce mois-ci

Commenter la réponse de cgandco
Messages postés
345
Date d'inscription
mardi 1 juin 2004
Statut
Membre
Dernière intervention
17 octobre 2014
3
3
Merci
bonjour,

la forme "from x, y, z ..." nécessite la présence simultanée de toutes les conditions.
Avec les données que tu montre, le résultat est nul !

il faut faire des "left join" pour obtenir ce que tu veux : lien x->y OU x->z

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 197 internautes nous ont dit merci ce mois-ci

Commenter la réponse de tpoinsot
Messages postés
1540
Date d'inscription
lundi 26 mai 2003
Statut
Membre
Dernière intervention
1 août 2013
11
3
Merci
Salut,

perso j'aurais mergé les tables Y & Z pour ensuite faire une jointure normale :

SELECT *
  FROM X,
      (SELECT FY AS FYZ FROM Y UNION ALL SELECT FZ AS FYZ FROM Z) YZ
 WHERE X.FK = YZ.FYZ;


pas sûr que ce soit la méthode la plus rapide,
mais pretty sûr que ça donne ce que tu souhaites ;)

bon SQL

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 197 internautes nous ont dit merci ce mois-ci

Commenter la réponse de cs_jopop
Messages postés
345
Date d'inscription
mardi 1 juin 2004
Statut
Membre
Dernière intervention
17 octobre 2014
3
3
Merci
Si, mais avec left/right join, tu auras 3 colonnes : CS_PERS/CodeCS, CS_PERS_PRO/CodeCS et CS_PERS_PRO/CODE_SERVICE, avec des vides. Pour obtenir 2 colonnes, tu remplaces les 2 dernières par un lien vers l'union de 2 tables.
Le tout en une seule requête. C'est la requête imbriquée qui pose un problème ?

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 197 internautes nous ont dit merci ce mois-ci

Commenter la réponse de tpoinsot
Messages postés
1540
Date d'inscription
lundi 26 mai 2003
Statut
Membre
Dernière intervention
1 août 2013
11
3
Merci
Comme quoi j'écris pas que des âneries

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 197 internautes nous ont dit merci ce mois-ci

Commenter la réponse de cs_jopop
Messages postés
345
Date d'inscription
mardi 1 juin 2004
Statut
Membre
Dernière intervention
17 octobre 2014
3
3
Merci
Si j'ai bien compris ce que tu cherches, il ne faut pas mettre le "where..." ni la référence à ENTITES telle que tu l'as mise, mais quelque chose comme
FROM (PERSONNE P LEFT JOIN (..) ENTITEPRO ON CS_PERS_PRO=CentrePro)
Left Join ENTITES E On P.CS_PERS=E.CodeCS

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 197 internautes nous ont dit merci ce mois-ci

Commenter la réponse de tpoinsot
Messages postés
345
Date d'inscription
mardi 1 juin 2004
Statut
Membre
Dernière intervention
17 octobre 2014
3
3
Merci
Pas de where pour le lien, sinon tu exiges la présence des 2 extrêmités, et ce n'est pas ce que tu veux.

From PERSONNE P left join HISTOCARRIERE H on P.MATRI_PERSONNE = H.Matricule

le reste doit aller

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 197 internautes nous ont dit merci ce mois-ci

Commenter la réponse de tpoinsot
Messages postés
60
Date d'inscription
dimanche 7 novembre 2010
Statut
Membre
Dernière intervention
4 août 2012
0
Merci
Bon j'ai décidé de mettre en ligne mon problème :



On peut retrouver le libelle du centre de secours d'une personne grâce à son code (CS_PERS pour les pompiers volontaire et CS_PERS_PRO pour les pompiers professionnel).

CS_PERS_PRO de la table PERSONNE peut etre soit un code de la table ENTITES soit un code de la table SERVICE_SEDIT.

Il me faut une requete qui me permet de prendre les matricules, noms, prénoms, les libellés des grades des volontaires et des professionnels (LIBELLE_GRADE des tables GRADE et GRADE_SEDIT), les libellé des centres de secours des volontaires et professionnels (LIBELLECS et LIBELLE_SERVICE des tables ENTITES et SERVICE_SEDIT) des peronnes ayant le statut de volontaire et professionnel à la fois (CS_PERS<>'' AND CS_PERS_PRO<>'').

Requête à revoir :

SELECT P.MATRI_PERSSONNE, E.LIBELLECS, S.LIBELLE_SERVICE, G.LIBELLE_GRADE as LBL_G_V , GS.LIBELLE_GRADE as LBL_G_P
FROM PERSONNE LEFT JOIN ENTITES ON PERSONNE.CS_PERS_PRO=E.CodeCS, PERSONNE LEFT JOIN SERVICE_SEDIT ON PERSONNE.CS_PERS_PRO=S.CODE_SERVICE, ENTITES E, SERVICE_SEDIT S, GRADE G, GRADE_SEDIT GS
WHERE P.CS_PERS=E.CS_PERS AND GS.CODE_GRADE=P.GRADE_PRO AND G.CODE_GRADE=P.GRADE_OBTENT AND NOT CS_PERS='' AND NOT CS_PERS_PRO='' AND P.CS_PERS=E.CodeCS;

--> je ne peux pas me repérer par rapport au CODE_STATUT pour sélectionner les pro et les volontaires car par défaut le statut (CODE_STATUT='VOL') est affecté à une personne volontaire ou volontaire et pro. Le statut (CODE_STATUT='PRO') ne donne que les professionnels.
Commenter la réponse de cartman29
Messages postés
345
Date d'inscription
mardi 1 juin 2004
Statut
Membre
Dernière intervention
17 octobre 2014
3
0
Merci
bonjour,

je vois que tu n'es pas prêt d'être au bout !

revoie la doc de ton sgbd sur le sql (qu'as-tu comme sgbd ?), en particulier les "join", "left" et right".

rapidement, tu fais :
- soit from t1, t2 where t1.x = t2.x : tu n'obtiens que les enregistrements liés
- soit from t1 left join t2 on t1.x = t2.x : tout t1 + les t2 liés

toi, tu as écrit un mix : from t1 left join t2 on t1.x, t2 where t1.x = t2.x
rien gagné, pas de résultat !
Commenter la réponse de tpoinsot
Messages postés
60
Date d'inscription
dimanche 7 novembre 2010
Statut
Membre
Dernière intervention
4 août 2012
0
Merci
Je travail sur une base existante hyperfile par le biais d'excel (odbc).
Commenter la réponse de cartman29
Messages postés
60
Date d'inscription
dimanche 7 novembre 2010
Statut
Membre
Dernière intervention
4 août 2012
0
Merci
Je bloque au niveau des jointures sur les 3 tables (PERSONNE, ENTITES, SERVICE_SEDIT).

J'ai fais une requête (qui ne convient pas) la plus clair possible :

SELECT E.LibelleCS as lbl, S.LIBELLE_SERVICE as lbl_pro
FROM PERSONNE P LEFT JOIN ENTITES E ON P.CS_PERS_PRO=E.CodeCS LEFT JOIN SERVICE_SEDIT S ON P.CS_PERS_PRO=S.CODE_SERVICE
WHERE P.CS_PERS=E.CODECS ;

C'est simple :
-1 table PERSONNE (table parente) avec deux colonnes (CS_PERS, CS_PERS_PRO)

-1 table ENTITES qui contient le libellé(LibelleCS) de CS_PERS et 'une fois sur deux' le libellé(LibelleCS) de CS_PERS_PRO

-1 table SERVICE_SEDIT qui contient le reste des libellés(LIBELLE_SERVICE) de CS_PERS_PRO

--------------------------------------------
info pour les relations (noms de colonnes) :

CS_PERS = CodeCS
CS_PERS_PRO = CodeCS ou CODE_SERVICE

--------------------------------------------
Je dois avoir comme résultat 2 colonnes :

lbl et lbl_pro
Commenter la réponse de cartman29
Messages postés
345
Date d'inscription
mardi 1 juin 2004
Statut
Membre
Dernière intervention
17 octobre 2014
3
0
Merci
Alors la solution de jopop est très bien.
As-tu essayé ?
Commenter la réponse de tpoinsot
Messages postés
60
Date d'inscription
dimanche 7 novembre 2010
Statut
Membre
Dernière intervention
4 août 2012
0
Merci
Il n'y a pas moyen de la faire en 1 requete ?
Commenter la réponse de cartman29
Messages postés
60
Date d'inscription
dimanche 7 novembre 2010
Statut
Membre
Dernière intervention
4 août 2012
0
Merci
Je n'ai jamais fait de requêtes imbriquées dans la clause 'FROM', seulement dans la 'WHERE'. (cf méthode de jopop)
Commenter la réponse de cartman29
Messages postés
60
Date d'inscription
dimanche 7 novembre 2010
Statut
Membre
Dernière intervention
4 août 2012
0
Merci
Géniale, je crois que c'est ça :

SELECT MATRI_PERSONNE, LBLPRO FROM PERSONNE, (SELECT LibelleCS as LBLPRO, CodeCS AS CentrePro FROM ENTITES UNION ALL SELECT LIBELLE_SERVICE as LBLPRO, CODE_SERVICE AS CentrePro FROM SERVICE_SEDIT) ENTITEPRO WHERE PERSONNE.CS_PERS_PRO = ENTITEPRO.CentrePro
Commenter la réponse de cartman29
Messages postés
60
Date d'inscription
dimanche 7 novembre 2010
Statut
Membre
Dernière intervention
4 août 2012
0
Merci
Plus dur maintenant, disons que dans CS_PERS il y a quelque chose et que dans CS_PERS_PRO il n'y a rien, comment je peux faire pour que ca me sélectionne quand même le champs vide ?
Commenter la réponse de cartman29
Messages postés
60
Date d'inscription
dimanche 7 novembre 2010
Statut
Membre
Dernière intervention
4 août 2012
0
Merci
comment je peux faire ma jointure externe ?
Commenter la réponse de cartman29
Messages postés
60
Date d'inscription
dimanche 7 novembre 2010
Statut
Membre
Dernière intervention
4 août 2012
0
Merci
Ceci me donne le même résultat :/ :

SELECT P.MATRI_PERSONNE, P.NOM_PERS, P.PRENOM_PERS, LBLPRO, E.LibelleCS FROM ENTITES E, PERSONNE P LEFT JOIN (SELECT LibelleCS as LBLPRO, CodeCS AS CentrePro FROM ENTITES UNION ALL SELECT LIBELLE_SERVICE as LBLPRO, CODE_SERVICE AS CentrePro FROM SERVICE_SEDIT) ENTITEPRO ON CS_PERS_PRO=CentrePro WHERE P.CS_PERS=E.CodeCS
Commenter la réponse de cartman29
Messages postés
60
Date d'inscription
dimanche 7 novembre 2010
Statut
Membre
Dernière intervention
4 août 2012
0
Merci
Merci déjà pour tout ce que vous avez fait (tpoinsot, jopop,... :) ). J'ai une dernière question à laquelle j'ai passé toute ma journée d'hier sans y trouver de réponses :

J'ai ma table
PERSONNE(colonne MATRI_PERSONNE,...)
et une table
HISTOCARRIERE(colonne Matricule, DATE_GRADE)

Je cherche à prendre toutes les MAX(DATE_GRADE) de chaque matricules (matricule unique avec la date maximum de celui-ci) et si il manque un matricule il faut quand même que ça ajoute la le matricule.

J'arrive à faire cette requête sauf avec la dernière condition :

"SELECT P.DATE_NAISS, MAX(H.DATE_GRADE) as dtgrade, P.MATRI_PERSONNE, P.ADR_PERS, P.CP_PERS, G.LIBELLE_GRADE as Grade, P.VILLE_PERS, P.NOM_PERS, P.PRENOM_PERS, E.LibelleCS FROM HISTOCARRIERE H, GRADE G, ENTITES E, PERSONNE P WHERE P.CS_PERS=E.CodeCS AND CS_PERS_PRO='' AND P.GRADE_OBTENT=G.CODE_GRADE AND P.MATRI_PERSONNE=H.Matricule AND " & chaine & " GROUP BY P.DATE_NAISS, P.MATRI_PERSONNE, G.LIBELLE_GRADE, P.ADR_PERS, P.CP_PERS, P.VILLE_PERS, P.NOM_PERS, P.PRENOM_PERS, E.LibelleCS;"

Je pense qu'il faut faire quelque chose comme :

WHERE DATE_GRADE=(SELECT MAX(DATE_GRADE) AS dte FROM HISTOCARRIERE) avec une jointure gauche mais je n'y arrive pas :/
Commenter la réponse de cartman29