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

Requêtes MySQL Discussion :

[Débutant] Comment faire au mieux une jointure


Sujet :

Requêtes MySQL

  1. #1
    Débutant  
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 096
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 096
    Points : 944
    Points
    944
    Par défaut [Débutant] Comment faire au mieux une jointure
    Bonjour à tous,
    J'ataque les jointures et j'ai trouvé un petit soft MyQSLWorkbrench qui ma permis de modeliser ma base de donnée.
    Ce soft ma extrait le code sql pour l'importer dans MySQL et construire donc ma base de donnée
    Avec ce soft, j'ai choisi, notemment de faire un jointure n:m et c'est là dessus que je souhaite avoir votre aide.

    Schématiquement ca donne ceci

    tb_etablissement
    - id_etablissement INT
    - fd_nom
    - etc.....

    tb_products
    - id_products
    - tb_etablissement_id_etablissement INT
    - tb_products_type_id_product_type INT

    tb_products_type
    - id_product_type INT
    - fd_product_type_name
    La table tb_products fait la liaison avec les deux autres.
    Dans la table tb_etablissement j'ai qu'un etablissement, mais je pourrais en avoir plusieur

    Dans la table tb_products j'ai les produits_type dont l'établissement a souscris par exemple:
    (id_products=>tb_etablissement_id_etablissement=>tb_products_type_id_product_type)
    1=>1=>1
    2=>1=>3
    1=>1=>6
    Dans la table tb_products_type j'ai
    1=>Hotel
    2=>Camping
    3=>Web
    4=>Support
    5=>Telephonie
    6=>Informatique
    7=>Autre
    Voilà, j'espère que mon shcéma est compréhensible

    Ce que je ne sais pas trop faire, c'est comme faire un requete MySQL la plus propre possible en utilisant les jointure comme JOIN ON.
    Ceci pour connaitre à quels options s'est souscris l'établissement ayant l'id id_etablissement?

    Pourriez-vous me montrer un exemple?

  2. #2
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Il n'y a pas de piège :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT * FROM tb_etablissement
    JOIN tb_products ON tb_etablissement_id_etablissement = id_etablissement
    JOIN tb_products_type ON tb_products_type_id_product_type = id_product

  3. #3
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    sabotage +1, donc rien à rajouter.

    Je remarque cependant que tu utilise systématiquement des noms presque à rallonge, qui me donne le sentiment que tu t'oblige à les nommer chaque de manière unique.

    Ce n'est pas obligatoire, mais ça ne veut pas dire que ce n'est pas correcte
    Est ce si indispensable que ça ?

    Chacun sa manière de faire, mais il ne faudrait pas exclure que SQL permet de désigner, de préfixer chaque champ par le nom de la table afin d'éliminer l'ambiguïté qu'il y aurait lorsque le nom d'un champ est le même dans 2 tables (ou plus).
    SQL permet aussi de définir des alias aux tables, ce qui simplifie encore d'avantage la requête.

    etablissement
    - id_etab
    - nom
    - etc.....

    products
    - id_products
    - id_etab
    - type_id

    products_type
    - id_type
    - nom
    Exemple avec des alias :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT p.id_products, e.nom AS nom_etab, e.id_etab, t.id_type, t.nom AS nom_type
    FROM etablissement e
    JOIN products p ON e.id_etab = p.id_etab
    JOIN products_type t ON t.id_type = p.id_type
    Encore une fois, chacun sa manière, mais personnellement je trouve ceci nettement plus lisible, aussi bien au niveau des tables qu'au niveau de la requête, au bout, c'est la compréhension de la requête qui s'en trouve améliorée.

    Toutes tables/champs sont aliasés dans la requête, donc un coup d'oeil suffit pour savoir à quelle table tel champ appartient, et c'est cela qui évitera une erreur SQL genre "ambigous field ...".


    C'était une petite parenthèse bien sûr

  4. #4
    Débutant  
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 096
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 096
    Points : 944
    Points
    944
    Par défaut
    Encore merci pour vos réponses!!!!

    Je ne sais pas si je fais bien d'avoir utiliser MySQLWorkBrench même si c'est un soft super, mais que je découvre en meme temps que cherche à perfectionner mes connaissances avec MySQL, dont les jointure.

    J'ai peur que ca me brouille....

    J'ai donc fait un jointure comme ceci et ca marche bien !!!!
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT * FROM tb_objets_tarifs 
    INNER JOIN tb_products ON tb_objets_tarifs.fd_product=tb_products.id_product 
    WHERE tb_products.fd_subscribed = 1 
    ORDER BY id_objets_tarifs';
    Cool, c'est ma premiere.

    Cependant je suis un peu confu.

    J'ai lu un peu de théorie sur les jointures et il était dit que la colonne que je veux jointre doit etre la meme que celle de ma premiere table
    expl:
    tb_maisons
    - id_maison
    - espace
    - piece
    - proprietaire

    tb_immeuble
    - id_immeuble
    - étage
    - appartement
    - proprietaire
    Dans le cas ci-dessus, je vais faire une jointure pour extraire tous les mobilier qui ont le meme propietaire.

    Es-ce que c'est de la théorie? car dans mon code PHP que j'ai mis ci-dessus, la joiture se fait sur deux colonne qui ont un nom différent (fd_products et id_product)

    J'ai aussi un peu l'impression que MySQLWprkbrench me brouille ( je ne le connais pas beaucoup) d'ou ma deuxième question.

    Es-ce que les deux colonnes qui vont être utlisés pour la jointure doivent être "primaire"?

    Aussi, que risque-je si je ne ne choisi pas de colonne qui "s'autoincrément" ( a par les doublons)?

    Pour finir, es-ce qu'une table doit obligatoirement avoir une clé primaire?
    Je pense que peut etre je peux répondre à cette question : Si aucune colonne est "primaire" (primary), je ne peux pas faire d'indexation. Corrigez moi! :o)

    Encore un petit truc, concernant l'indexation (je veux peux etre aller trop vite). faut mieux indexé une colonne qui est primaire ou alors une colonne avec laquel on fait une jointure. je dirais le deuxième cas. Non?


    Milles mercis pour vos lumières

  5. #5
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 799
    Points : 34 046
    Points
    34 046
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par pierrot10 Voir le message
    Je ne sais pas si je fais bien d'avoir utiliser MySQLWorkBrench même si c'est un soft super, mais que je découvre en meme temps que cherche à perfectionner mes connaissances avec MySQL, dont les jointures.

    J'ai peur que ça me brouille....
    Ça dépend de ta connaissance de départ en modélisation.
    Si tu maîtrises la modélisation en MCD de la méthode Merise, tu seras peut-être légèrement dérouté par le schéma Entité/Relation de MySQL Workbench, qui est plus proche du MLD et il n'est pas toujours évident de modéliser directement en MLD ou Schéma E/R.

    Si tu maîtrises davantage le diagramme de classes UML, tu devrais à peu près retrouver tes petits avec le schéma E/R, à la schématique près.

    Sinon, MySQL Workbench est un bon outil pour modéliser, surtout si tu utilises le SGBD MySQL car pour un autre SGBD, il faudra adapté le script SQL généré par le logiciel pour le nouveau SGBD.

    J'ai donc fait un jointure comme ceci et ca marche bien !!!!
    Code PHP :
    SELECT * FROM tb_objets_tarifs INNER JOIN tb_products ON tb_objets_tarifs.fd_product=tb_products.id_product WHERE tb_products.fd_subscribed = 1 ORDER BY id_objets_tarifs';
    Plus haut, RunCodePhp te suggérait d'utilider des alias, ce qui améliore grandement la lisibilité de la requête. De plus, évite la guerre des étoiles !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT les_colonnes_necessaires
    FROM tb_objets_tarifs AS t
    INNER JOIN tb_products AS p ON t.fd_product = p.id_product 
    WHERE p.fd_subscribed = 1 
    ORDER BY t.id_objets_tarifs
    J'ai lu un peu de théorie sur les jointures et il était dit que la colonne que je veux joindre doit être la même que celle de ma première table
    Ce n'est pas exactement ça.
    Tu as le droit de faire référence à une colonne qui ne porte pas le même nom que celui de la colonne qui porte la clé étrangère mais il faut que ce soit logiquement cohérent.
    En principe, les clés étrangères font références à des clés primaires et c'est ce que tu sembles avoir fait dans ta requête.
    Pour plus de détail sur les jointures, voir le cours de SQLPro.

    tb_maisons
    - id_maison
    - espace
    - piece
    - proprietaire

    tb_immeuble
    - id_immeuble
    - étage
    - appartement
    - proprietaire
    Dans le cas ci-dessus, je vais faire une jointure pour extraire tous les mobiliers qui ont le même propiétaire.

    Es-ce que c'est de la théorie? car dans mon code PHP que j'ai mis ci-dessus, la jointure se fait sur deux colonnes qui ont un nom différent (fd_products et id_product)
    Ce n'est pas un problème, comme je l'ai expliqué plus haut, du moment que c'est cohérent sur le plan logique et sémantique. Personnellement, comme je préfixe toutes mes colonnes d'un code mnémotechnique relatif à la table, je n'ai jamais deux colonnes portant le même nom.
    Par contre, ta requête ne correspond pas du tout à la description des tables que tu donnes, lesquelles semblent être des spécialisations de produits non ?

    Es-ce que les deux colonnes qui vont être utlisés pour la jointure doivent être "primaire"?
    Généralement non. Exemples :
    1) Cas général
    Soit le MCD suivant :
    Personne -0,n----Diriger----1,1- Projet

    Ça donne le schéma E/R suivant dans MySQL Workbench :
    Personne -|o-------------< Projet

    J'ai l'habitude de lire ce schéma : "Une personne (symbole -|) peut (symbole o) donner sa clé à plusieurs projets (symbole < qui est plutôt une patte d'oie dans MySQL Workbench)."

    Les tables auront par exemple cette composition :
    Personne (prs_id, prs_nom, prs_prenom...)
    Projet (prj_id, prj_id_chef_projet, prj_nom...)

    prj_id_chef_projet est une clé étrangère faisant référence à l'identifiant de la personne faisant fonction de chef de projet, donc la clé primaire de la table Personne.

    2) Cas de l'héritage
    Je vais maintenant considérer que la table personne peut aussi bien contenir des salariés que des contacts externes (chez les clients ou les fournisseurs) et je vais spécialiser mon entité Personne :
    Salarié -(1,1)----Etre----0,1- Personne

    Les cardinalités entre parenthèses signifient que le salarié sera identifié relativement à la personne, donc que son identifiant sera celui de la personne. L'entité Salarié hérite de l'entité Personne.

    Ça donne par exemple les tables suivantes :
    Personne (prs_id, prs_nom, prs_prenom...)
    Salarie (slr_id_personne, slr_matricule, slr_taux_horaire...)

    slr_id_personne est ici à la fois clé primaire et clé étrangère.

    Aussi, que risqué-je si je ne ne choisis pas de colonne qui "s'auto-incrémente" ( à part les doublons)?
    Les clés primaires issues des entités seront de préférence des entiers auto-incrémentés. Par voie de conséquence, les clés primaires issues d'associations du MCD seront composées des identifiants des tables entrant en jeu dans l'association et seront donc aussi des entiers mais pas auto-incrémentés.

    Exemple de MCD :
    Salarie -0,n----Travailler----0,n- Projet

    Tables qui en découlent :
    Salarie (slr_id_personne, slr_matricule, slr_taux_horaire...)
    Projet (prj_id, prj_id_chef_projet, prj_nom...)
    Salarie_travailler_projet (stp_id_salarie, stp_id_projet...)

    La clé primaire est ici composée de deux clés étrangères faisant référence aux clés primaires des tables entrant en jeu dans l'association Travailler du MCD.

    Pour finir, est-ce qu'une table doit obligatoirement avoir une clé primaire?
    Oui.
    Dans la pratique, il est techniquement possible de faire une table sans clé primaire mais c'est une très mauvaise idée ! phpMyAdmin signale d'ailleurs cette anomalie quand on y crée une table sans clé primaire.

    Je pense que peuttre je peux répondre à cette question : Si aucune colonne est "primaire" (primary), je ne peux pas faire d'indexation. Corrigez moi! :o)
    Non.
    La clé primaire est automatiquement indexée.
    Mais si tu crées une table sans clé primaire, tu peux ensuite mettre un index simple ou UNIQUE sur une ou plusieurs colonnes de la table.
    À noter que les colonnes porteuses de clé étrangère doivent être indexées. phpMyAdmin le fait désormais automatiquement. Ainsi que MySQL Workbench d'ailleurs.

    Encore un petit truc, concernant l'indexation (je veux peux etre aller trop vite). faut mieux indexé une colonne qui est primaire ou alors une colonne avec laquel on fait une jointure. je dirais le deuxième cas. Non?
    Compte-tenu de ce que j'ai dit juste avant : les deux mon capitaine !

    Les index minimums sont :
    - la clé primaire ;
    - la ou les clés étrangères.

    Nota :
    Dans ma table Salarie_travailler_projet (stp_id_salarie, stp_id_projet...), il y aura :
    - l'index de clé primaire (stp_id_salarie, stp_id_projet) dans lequel la colonne stp_id_salarie sera automatiquement indexée de manière individuelle, grâce à son index conjoint à stp_id_projet ;
    - l'index individuel sur la colonne stp_id_projet car cette colonne n'est pas indexée automatiquement par la clé primaire.

    La clé primaire peut en effet être indexée de cette manière :
    stp_id_salarie, stp_id_projet
    1, 2
    1, 3
    1, 5
    2, 1
    2, 2
    2, 5
    => On voit ci-dessus que stp_id_projet n'apparaît pas dans l'ordre. Il faut donc un index supplémentaire individuellement sur la colonne stp_id_projet.

    Bon courage !

  6. #6
    Débutant  
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 096
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 096
    Points : 944
    Points
    944
    Par défaut
    Salut CinePhil,

    Je te remercie pour ta grande explication . Elle juste enorme et complete. Je vais prendre le temps de tout lire en détail.
    MERCI!! C'est génial

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 18/11/2010, 17h00
  2. Réponses: 3
    Dernier message: 03/10/2007, 00h59
  3. [C#][Débutant] Comment faire une fonction FindWindow ?
    Par Cazaux-Moutou-Philippe dans le forum Windows Forms
    Réponses: 4
    Dernier message: 27/04/2006, 13h19
  4. [Débutant]Comment faire des tranches de nombre dans une tabl
    Par Jedecouvreaccess dans le forum Access
    Réponses: 7
    Dernier message: 05/09/2005, 08h46
  5. comment faire pour qu'une application soit toujours visible ?
    Par goldbar dans le forum Langages de programmation
    Réponses: 2
    Dernier message: 28/03/2004, 14h35

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