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
    Probleme INNERJOIN 3 tables (Bonne Méthode)
    Bonjour!
    Je bug sur un innerjoin

    J'ai 3 tables.
    La 1ere contient:


    [TH="colspan:2"]Produits_id[/TH]
    [TH]id[/TH]
    [TH]nom[/TH]
    1 Vin
    2 Soda

    La 2eme :

    [[TH="colspan:3"]Produits_vin[/TH]
    [TH]id[/TH]
    [TH]nom[/TH]
    [TH]Produit[/TH]
    1 Bordeaux Vin
    2 Piquete Vin

    La 3eme :


    [TH="colspan:3"]Produits_soda[/TH]
    [TH]id[/TH]
    [TH]nom[/TH]
    [TH]Produit[/TH]
    1 Cola Soda
    2 Fanta Soda
    3 Sprite Soda

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


    [TH]Type_de_Produit[/TH]
    [TH]Nom_Produit[/TH]
    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
    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
    J'ai édité le message avec ce que j'ai comme code si cela peut aider

  4. #4
    Expert éminent
    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

    La 1ere contient:

    [TH="colspan:2"]Produits_id[/TH]
    [TH]id[/TH]
    [TH]nom[/TH]
    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 :

    [[TH="colspan:3"]Produits_vin[/TH]
    [TH]id[/TH]
    [TH]nom[/TH]
    [TH]Produit[/TH]
    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.


    [TH="colspan:3"]Produits_soda[/TH]
    [TH]id[/TH]
    [TH]nom[/TH]
    [TH]Produit[/TH]
    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 :


    [TH]Type_de_Produit[/TH]
    [TH]Nom_Produit[/TH]
    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
    Au niveau conceptuel, vous devriez avoir le modèle suivant



    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
    Merci d'avoir répondu, je teste et j'apprends en même temps. Dessolé de ne pas avoir répondu avant.

###raw>template_hook.ano_emploi###