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 :

Jointures ? Alias ?


Sujet :

SQL Oracle

  1. #1
    Membre à l'essai
    Jointures ? Alias ?
    Bonjour,

    je reprends le langage SQL après une longue pause, et je patauge sur une requête.

    J'ai trois tables :
    Chantier(IDChantier, Numero, NumeroReel, Titre, Nom, IDContact)
    Contact(IDContact, Nom, Prenom)
    ChantierFrais(IDChantierFrais, IDChantier, Date, Type, IDContact, Description, Montant, Monnaie, Reference)

    Je veux établir une requête qui me donne en sortie une liste :
    NumeroReel, Nom (contactChantier), Prenom (contact Chantier), Titre (du chantier), Nom (du chantier), date de la dépense (frais), type (frais), référence (frais), nom du contact du frais, description (frais), montant (frais).

    1) La liste en réponse sera une liste de dépenses (frais) triée par NumeroReel de chantier ;
    2) Il faut "juste" que je récupère dans un premier temps le nom du contact dont l'id est dans la table contact (pour afficher le nom du contact et pas son id dans la liste des frais)
    3) Il faut que je récupère les informations liées au chantier pour afficher le numéro reel du chantier, son titre, son nom, le nom de son contact, le prenom de son contact (donc jointure avec la table Contact)

    Plus que la réponse, c'est de retrouver les automatismes d'élaboration d'une requête qui m'intéresse, si quelqu'un a le temps de m'expliquer le raisonnement, je suis preneur.

  2. #2
    Membre chevronné
    Bonjour,


    Il faut procéder par étape pour construire la requête répondant à vos différents critères.
    Nous allons donc la décomposer comme suit :

    2) Il faut "juste" que je récupère dans un premier temps le nom du contact dont l'id est dans la table contact
    On part donc de la table contact ce qui nous donne :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    SELECT IDContact
    FROM Contact;


    3) Il faut que je récupère les informations liées au chantier
    Ensuite nous voulons les chantiers associés à ce contact, on joint les deux tables :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT Contact.IDContact, Chantier.IDChantier
    FROM Contact 
      INNER JOIN Chantier
        ON Contact.IDContact = Chantier.IDContact;


    1) La liste en réponse sera une liste de dépenses (frais) [..];
    Il faut donc aussi associer la dernière table :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT Contact.IDContact, Chantier.IDChantier, ChantierFrais.IDChantierFrais
    FROM Contact 
      INNER JOIN Chantier
        ON Contact.IDContact = Chantier.IDContact;
        INNER JOIN ChantierFrais
          ON Chantier.IDChantier= ChantierFrais.IDChantier
          AND Chantier.IDContact = ChantierFrais.IDContact;


    1) [..] triée par NumeroReel de chantier
    Ajout du tri

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT Contact.IDContact, Chantier.IDChantier, ChantierFrais.IDChantierFrais
    FROM Contact 
      INNER JOIN Chantier
        ON Contact.IDContact = Chantier.IDContact;
        INNER JOIN ChantierFrais
          ON Chantier.IDChantier= ChantierFrais.IDChantier
          AND Chantier.IDContact = ChantierFrais.IDContact
    ORDER BY NumeroReel;



    Ne reste plus qu'à afficher les informations qui vous intéressent

  3. #3
    Membre à l'essai
    Bonjour Scriuiw,

    Merci de votre réponse didactique, j'ai aimé les étapes que vous avez formalisées.

    Malheureusement ça ne répond pas à mon besoin, car je l'ai sans nul doute mal formulé ce que je cherche à obtenir.

    Toutes les informations dont j'ai besoin sont dans la table ChantierFrais.
    Je pourrais faire un select * sur cette table j'aurais toutes les informations.

    Sauf que l'information IDContact n'est pas explicite, je souhaite donc remplacer la colonne IDContact (de ChantierFrais) par le nom du contact.
    Donc je pense qu'il m'est nécessaire de faire une jointure entre les tables
    ChantierFrais et Contact.

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT ChantierFrais.IDChantier, ChantierFrais.Date, ChantierFrais.Type,ChantierFrais.Description, ChantierFrais.Montant, ChantierFrais.Monnaie, ChantierFrais.Reference
    FROM ChantierFrais
    FULL JOIN Contact ON ChantierFrais.IDContact = Contact.IDContact


    ça c'est OK.

    L'information IDChantier n'est pas explicite, je cherche donc à remplacer chaque IDChantier par :
    NumeroReel, Titre, Contact du chantier
    Donc je pense à une jointure entre les tables ChantiersFrais et Chantier


    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT Chantier.NumeroReel, Chantier.Titre, Chantier.IDContact, ChantierFrais.Date, ChantierFrais.Type,ChantierFrais.Description, ChantierFrais.Montant, ChantierFrais.Monnaie, ChantierFrais.Reference, Contact.Nom, Contact.Prenom, Contact.Societe 
    FROM ChantierFrais
    FULL JOIN Contact ON ChantierFrais.IDContact = Contact.IDContact
    FULL JOIN Chantier ON ChantierFrais.IDChantier = Chantier.IDChantier


    Et encore une fois, dans les informations récupérées du chantier, l'information IDContact ne sera pas explicite, je dois donc la remplacer par le Nom, Prénom du contact

    Donc une jointure entre Chantier et Contact.

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    Code erroné


    Je m'emmêle dans mes jointures successives...

    Pour cette dernière étape je ne sais pas comment faire pour distinguer l'information du contact du chantier, de l'information du contact de la dépense (frais chantier).

    Je pense que je suis dans un cas scolaire de jointure entre 3 tables.
    Je vais rechercher sur le net.

    Si vous avez des pistes à me proposer ou des remarques sur le code proposé, je suis à l'écoute.

    Bien à vous

  4. #4
    Membre chevronné
    Là ou ce n'est pas clair pour moi, c'est au niveau du modèle de données car rien n'est précisé

    On a 3 tables :
    Chantier(IDChantier, Numero, NumeroReel, Titre, Nom, IDContact)
    Contact(IDContact, Nom, Prenom)
    ChantierFrais(IDChantierFrais, IDChantier, Date, Type, IDContact, Description, Montant, Monnaie, Reference)

    IDContact apparaît dans chaque table par contre la jointure à la table ChantierFrais se fait :
    1) Uniquement à l'aide de IDChantier provenant de la table Chantier ce qui signifie que ChantierFrais.IDContact peut être différent de Chantier.IDContact
    Auquel cas, ce qui vous intéresse c'est de récupérer le nom du contact de Chantier et le contact de ChantierFrais
    2) A l'aide des champs IDChantier provenant de la table Chantier et IDContact de Contact ce qui signifie que l'information est forcément identique et redondante dans la table ChantierFrais

    Suite à votre réponse, je pencherais pour la solution 1.
    Il faut dans ce cas faire une double jointure à la table Contact (Et ne pas la prendre comme base de votre requête qui sera plutôt axée sur la table Chantier jointe à la fois à Contact et ChantierFraispuis ensuite ChantierFrais jointe à Contact aussi

  5. #5
    Membre à l'essai
    En effet, je n'ai pas le modèle de données exact des tables (concernant les clefs primaires ou secondaire), je n'ai qu'un utilitaire et une liste dépliante des champs des tables.
    Désolé pour ce caractère "boite grise".

    Effectivement :
    - Le contact d'un ChantierFrais est en français le "fournisseur" chez qui nous achetons le matériel ;
    - Le contact d'un Chantier est le client pour lequel nous réalisons des travaux ;


    Il faut dans ce cas faire une double jointure à la table Contact (Et ne pas la prendre comme base de votre requête qui sera plutôt axée sur la table Chantier jointe à la fois à Contact et ChantierFraispuis ensuite ChantierFrais jointe à Contact aussi
    Je vais étudier cette approche de double jointure

  6. #6
    Membre à l'essai
    Cette requête devrait répondre à votre demande:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT NumeroReel , CCHA.Nom Nom_Cont_Chatier, CCHA.Prenom Prenom_Cont_Chatier,
     
           Titre, CHA.Nom Nom_Chantier, Date, Type, Reference,
     
           CFRS.Nom Nom_Cont_Frais, description, montant
     
    From   Chantier CHA, ChantierFrais FRS, Contact CCHA, Contact CFRS
     
    WHERE  CHA.IDChantier = FRS.IDChantier
     
    AND    CHA.IDContact = CCHA.IDContact
     
    AND    FRS.IDCOntact = CFRS.IDContact;

  7. #7
    Membre à l'essai
    Merci beaucoup Mahdois

    C'est parfaitement ce que je cherchais à réaliser.

    Je retiens les deux astuces :
    1) créer deux alias d'une même table pour ne pas devoir faire deux select imbriqués ;
    2) renommer les colonnes en sortie (j'avais oublié cette option de présentation du résultat de la requête) ;

    Bonne fin d'année !