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

Requêtes MySQL Discussion :

Probleme INNERJOIN 3 tables (Bonne Méthode)


Sujet :

Requêtes MySQL

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    juillet 2003
    Messages
    257
    Détails du profil
    Informations personnelles :
    Localisation : Espagne

    Informations forums :
    Inscription : juillet 2003
    Messages : 257
    Points : 98
    Points
    98
    Par défaut Probleme INNERJOIN 3 tables (Bonne Méthode)
    Bonjour!
    Je bug sur un innerjoin

    J'ai 3 tables.
    La 1ere contient:

    Produits_id
    id nom
    1 Vin
    2 Soda

    La 2eme :
    Produits_vin
    id nom Produit
    1 Bordeaux Vin
    2 Piquete Vin

    La 3eme :

    Produits_soda
    id nom Produit
    1 Cola Soda
    2 Fanta Soda
    3 Sprite Soda

    Je voudrais créer une requête de telle manière à retrouver ceci :

    Type_de_Produit Nom_Produit
    Vin Bordeaux
    Vin Piquete
    Cola Soda
    Fanta Soda
    Sprite Soda

    J'ai essayé ceci mais sans succès.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT Produits_id.nom, Produits_vin.nom, Produits_soda.nom
    FROM Produits_id
    INNER JOIN Produits_vin ON Produits_id.nom = Produits_vin.nom
    INNER JOIN Produits_soda ON Produits_id.nom = Produits_soda.nom
    Merci d'avance.

  2. #2
    Expert éminent
    Homme Profil pro
    Responsable Datas
    Inscrit en
    janvier 2009
    Messages
    3 948
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Datas

    Informations forums :
    Inscription : janvier 2009
    Messages : 3 948
    Points : 9 186
    Points
    9 186
    Par défaut
    Bonjour,
    Tu nous dis que tu as un "bug", mais sans plus d'informations on ne peut pas t'aider.
    Comment pourrions-nous te dire ce qui ne va pas dans ta requête sans connaitre cette dernière, ni le message d'erreur ?
    qui plus est tu nous montre le contenu de tes tables, mais sans la structure...

    Tatayo.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    juillet 2003
    Messages
    257
    Détails du profil
    Informations personnelles :
    Localisation : Espagne

    Informations forums :
    Inscription : juillet 2003
    Messages : 257
    Points : 98
    Points
    98
    Par défaut
    J'ai édité le message avec ce que j'ai comme code si cela peut aider

  4. #4
    Expert éminent
    Homme Profil pro
    Responsable Datas
    Inscrit en
    janvier 2009
    Messages
    3 948
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Datas

    Informations forums :
    Inscription : janvier 2009
    Messages : 3 948
    Points : 9 186
    Points
    9 186
    Par défaut
    On ne sais toujours pas ce qui ne va pas (même si je pense l'avoir deviné en regardant la requête et le schéma des tables).

    Mais déjà je note un problème de conception: je vois dans les tables produit_vin et produit_soda le nom du produit.
    Il faut utiliser l'identifiant des lignes de produit comme clé étrangère dans ces tables, et non le nom.
    Si tu renommes un produit, tout ton schéma s'effondre.

    Ensuite dans la requête, la première incohérence est que tu fais la jointure entre le nom d'un produit, et le nom d'un produit_vin. Donc tu cherches des lignes qui vérifient cette égalité: vin = piquete.
    Tu ne risques pas de trouver grand-chose…
    Si tu veux persister dans ce schéma bancale, la jointure doit se faire entre la colonne nom de produit et la colonne produit de produit_vin. Idem pour l'autre table.

    Deuxième incohérence: tu cherches une correspondance pour chaque ligne de produit avec une ligne de produit_vin ET de produit_soda. A part si il existe un coca de Bourgogne, tu ne trouveras rien non plus.

    Donc ma conclusion est que tu devrais revoir complètement ton schéma. Je verrais bien
    • une table Type Produit (avec un id et un nom), qui contient ici 2 lignes: Vin et Soda
    • Une table Produit, avec un lien vers la table Type Produit (via son Id !). Elle contient dans ton exemple 5 lignes ici: Fanta, Sprite, Bordeaux, Cola et Piquete.

    Ainsi tu obtiendras ce que tu cherches bien plus facilement, avec une simple jointure. Et si tu ajoutes un autre type de produit, dans ton exemple il faut une autre table, et revoir toutes les requêtes. Dans mon exemple il suffit d'ajouter une ligne dans la table Type Produit.

    Tatayo.

  5. #5
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    août 2006
    Messages
    16 186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : août 2006
    Messages : 16 186
    Points : 32 327
    Points
    32 327
    Billets dans le blog
    12
    Par défaut
    La 1ere contient:
    Produits_id
    id nom
    1 Vin
    2 Soda
    Il s'agit donc ici de types de produits et non pas de produits.
    => Votre table est mal nommée !

    La 2eme :
    Produits_vin
    id nom Produit
    1 Bordeaux Vin
    2 Piquete Vin
    La troisième colonne semble reprendre le nom du (type de) produit de la première table.
    => Pourquoi ne pas utiliser plutôt l'identifiant du (type de) produit ?
    C'est comme ça qu'on répartit les données dans une base de données relationnelle ! Ensuite, on utilise les jointure pour retrouver les valeurs textuelles des clés étrangères référençant les autres tables.

    Produits_soda
    id nom Produit
    1 Cola Soda
    2 Fanta Soda
    3 Sprite Soda
    => Idem ci-dessus.

    Je voudrais créer une requête de telle manière à retrouver ceci :

    Type_de_Produit Nom_Produit
    Vin Bordeaux
    Vin Piquete
    Cola Soda
    Fanta Soda
    Sprite Soda

    J'ai essayé ceci mais sans succès.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT Produits_id.nom, Produits_vin.nom, Produits_soda.nom
    FROM Produits_id
    INNER JOIN Produits_vin ON Produits_id.nom = Produits_vin.nom
    INNER JOIN Produits_soda ON Produits_id.nom = Produits_soda.nom
    Le problème de votre requête est qu'un "produits_id" ne peut pas à la fois être un vin et un soda !
    => Il faut faire l'union de deux requêtes.
    Et comme vous avez utilisé le nom du "produit_id" plutôt que l'identifiant, par besoin de jointure !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT "Vin" AS Type_de_produit,
    	nom AS Nom_Produit
    FROM Produits_vin
    UNION
    SELECT "Soda",
    	nom 
    FROM Produits_soda
    ORDER BY Type_de_produit, Nom_Produit
    Revoyez la modélisation de votre base de données !
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  6. #6
    Expert éminent sénior

    Homme Profil pro
    bourreau
    Inscrit en
    mars 2010
    Messages
    4 891
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : mars 2010
    Messages : 4 891
    Points : 13 710
    Points
    13 710
    Billets dans le blog
    1
    Par défaut
    Au niveau conceptuel, vous devriez avoir le modèle suivant

    Nom : Sans titre.png
Affichages : 21
Taille : 6,2 Ko

    Ce qui donne les tables suivantes (PK soulignées, FK préfixées #) :

    YP_Type_Produit = (YP_id INT, YP_code CHAR(4), YP_libelle VARCHAR(50));
    PR_Produit = (PR_id INT, PR_reference CHAR(8), PR_libelle VARCHAR(128), #YP_id);
    Soit 2 tables et non pas 3

    Dans MySQL, vous déclarerez les colonnes YP_id et PR_id en type "auto_incrément"


    Avec le jeu d'essai suivant :
    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
    YP_ID YP_Code  YP_Libellé
    -----------------------------------------------------
    001   VISP      vins et spiritueux
    002   JUSF      jus de fruits et nectars
    003   SODA      sodas
    004   EAUM      eaux minérales
     
    PR_id   PR_reference  PR_libelle               YT_id
    -----------------------------------------------------
    0125    R005GB20      fanta orange             003
    1002    44812671      châteaux Margaux 1982    001
    0667    44812605      château Latour 1964      001
    0002    G61033F0      perrier                  004
    8019    AV510077      coka cola                003
    2704    66105922      jus de pommes            002

    Ce type de requête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    select YP_code
         , YP_libelle
         , PR_reference
         , PR_libelle
    from YP     
    inner join PR
       on PR.YP_id = YP.YP_id
    order by YP_code, PR_reference

    Donne le résultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    EAUM|eaux minérales          |G61033F0|perrier              
    JUSF|jus de fruits et nectars|66105922|jus de pommes        
    SODA|sodas                   |AV510077|coka cola            
    SODA|sodas                   |R005GB20|fanta orange         
    VISP|vins et spiritueux      |44812605|château Latour 1964  
    VISP|vins et spiritueux      |44812671|châteaux Margaux 1982

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    juillet 2003
    Messages
    257
    Détails du profil
    Informations personnelles :
    Localisation : Espagne

    Informations forums :
    Inscription : juillet 2003
    Messages : 257
    Points : 98
    Points
    98
    Par défaut
    Merci d'avoir répondu, je teste et j'apprends en même temps. Dessolé de ne pas avoir répondu avant.

Discussions similaires

  1. Probleme requete ALTER TABLE
    Par syseval dans le forum Langage SQL
    Réponses: 4
    Dernier message: 07/04/2005, 12h49
  2. PROBLEME AVEC UNE TABLE INTERBASE
    Par barro dans le forum InterBase
    Réponses: 1
    Dernier message: 22/09/2004, 08h16
  3. [EJB2.1 Entity] [CMP] Est-ce la bonne méthode ?
    Par stailer dans le forum Java EE
    Réponses: 8
    Dernier message: 20/06/2004, 19h42
  4. Probleme avec une table vide
    Par king dans le forum Bases de données
    Réponses: 5
    Dernier message: 20/03/2004, 14h24
  5. Probleme d'impression avec la méthode TForm->Print()
    Par Kid Icarus dans le forum C++Builder
    Réponses: 13
    Dernier message: 31/07/2002, 14h26

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