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 :

[MySQL] Vue, Jointure & Groupement


Sujet :

Requêtes MySQL

  1. #1
    Membre averti Avatar de GyZmoO
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    428
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2006
    Messages : 428
    Points : 301
    Points
    301
    Par défaut [MySQL] Vue, Jointure & Groupement
    Bonjour à tous.

    Je cherche la meilleure réponse à ma problématique.
    Je vous présenter mes tables :

    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    CREATE TABLE T_TEAM (
    	TEAM_ID SMALLINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    	TEAM_NAME VARCHAR(40)
    );
     
    CREATE TABLE T_PLAYER(
    	PLAYER_ID SMALLINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    	PLAYER_NAME VARCHAR(40),
    	PLAYER_NUMBER SMALLINT,
    	PLAYER_TEAM_ID SMALLINT
    	FOREIGN KEY (PLAYER_TEAM_ID) REFERENCES T_TEAM(TEAM_ID)
    );
     
    CREATE TABLE T_MATCH(
    	MATCH_ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    	MATCH_TEAM_DOMICILE SMALLINT,
    	MATCH_TEAM_EXT SMALLINT,
    	MATCH_SPECTATEURS INT,
    	FOREIGN KEY (MATCH_TEAM_DOMICILE) REFERENCES T_TEAM(TEAM_ID),
    	FOREIGN KEY (MATCH_TEAM_EXT) REFERENCES T_TEAM(TEAM_ID)
    );
     
    CREATE TABLE R_A_MARQUE(
    	R_A_MARQUE_ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    	R_A_MARQUE_MATCH_ID INT,
    	R_A_MARQUE_PLAYER_ID SMALLINT,
    	FOREIGN KEY (R_A_MARQUE_MATCH_ID) REFERENCES T_MATCH (MATCH_ID),
    	FOREIGN KEY (R_A_MARQUE_PLAYER_ID) REFERENCES T_PLAYER (PLAYER_ID)
    );
     
    CREATE TABLE R_A_PASSE(
    	R_A_PASSE_ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    	R_A_PASSE_MATCH_ID INT,
    	R_A_PASSE_PLAYER_ID SMALLINT,
    	FOREIGN KEY (R_A_PASSE_MATCH_ID) REFERENCES T_MATCH (MATCH_ID),
    	FOREIGN KEY (R_A_PASSE_PLAYER_ID) REFERENCES T_PLAYER (PLAYER_ID)
    );
    Grosso modo, je cherche à modéliser une ligue de football.
    Bref, j'ai une table qui représente les équipes, une qui représente les joueurs, une qui représente les matches. Ensuite, j'ai des tables "d'associations" R_A_MARQUE, & R_A_PASSE. Une ligne dans la table R_A_MARQUE signifie que le joueur X a marqué un but lors du match Y.Idem pour la table R_A_PASSE sauf que là c'est pour avoir réussi une passe.

    Bref jusque là, tout va bien.

    Maintenant je chercher à créer un vue résumant les informations pour un match donné et je voudrais un résultat de ce style :

    Nom équipe domicile - Score équipe domicile - Nb de passe équipe domicile - Nom équipe extérieur - Score équipe extérieur - Nb de passe équipe extérieur
    Et là je vous avoue que je ne sais pas DU TOUT comment faire...
    En fait ma question est : pensez vous qu'avec ce modèle actuel, je puisse répondre à cette problématique en une seule vue?
    Dois-je changer de modèle? (Par exemple ajouter des colonnes dans la table match pour avoir le nombre de but marqués par chaque équipe ainsi que le nombre de passes réussies... J'aime pas trop cette solution mais bon...).

    Je suis preneur de toutes remarques !!

    Merci d'avance

    Bonne journée et merci de m'avoir lu !
    define: Programmeur : Celui qui résout un problème que vous n'aviez pas, d'une façon que vous ne comprenez pas.

  2. #2
    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 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Il y a, conceptuellement parlant, un léger problème sur ton modèle de données. Sans contrainte intégrée à la BDD, rien n'interdit qu'un joueur marque un but dans un match que son équipe n'a pas joué !

    On va quand même supposer que ces contraintes existent pour répondre à ton besoin.

    Je trouve également bizarre que si un joueur fait 50 passes dans un match, tu ajoutes 50 lignes dans la table. J'aurais simplifié en indiquant le nombre de passe dans le match par un joueur en ajoutant une colonne R_A_MARQUE_NB_PASSES.

    Quant aux buts marqués, soit le même principe du nombre de buts pour chaque joueur lors d'un match, soit indiquer la minute au cours de laquelle a été marquée le but.

    Ainsi, tes deux tables R_A... deviennent des tables associatives qui n'ont pas besoin d'identifiant propre.

    Voici la requête pour compter le nombre de buts marqués par l'équipe à domicile lors du match 1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT t1.TEAM_NAME AS Nom_equipe_domicile,
    	COUNT(m1.R_A_MARQUE_ID) AS Score_equipe_domicile
    FROM T_TEAM t1
    INNER JOIN T_PLAYER p1 ON p1.PLAYER_TEAM_ID = t1.TEAM_ID
    	LEFT OUTER JOIN R_A_MARQUE m1 ON m1.R_A_MARQUE_PLAYER_ID = p1.PLAYER_ID
    WHERE m1.R_A_MARQUE_MATCH_ID = 1
    GROUP BY t1.TEAM_NAME
    Pour le nombre de passes, et avec ta structure actuelle, tu ajoutes une jointure vers R_A_PASSE et tu comptes de la même façon.

    Et pour l'équipe qui joue à l'extérieur, il faut partir du match entre les deux équipes et faire le même jeu de jointures.

    Je te laisse réfléchir à tout ça.
    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 !

  3. #3
    Membre averti Avatar de GyZmoO
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    428
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2006
    Messages : 428
    Points : 301
    Points
    301
    Par défaut
    Bonjour CinePhil et merci pour ta réponse !

    Je trouve également bizarre que si un joueur fait 50 passes dans un match, tu ajoutes 50 lignes dans la table. J'aurais simplifié en indiquant le nombre de passe dans le match par un joueur en ajoutant une colonne R_A_MARQUE_NB_PASSES.
    Bonne remarque, je vais simplifier ces tables de sorte à ajouter une colonne représentant le nombre de buts ou de passes pour un joueur donné et un match donné.

    Merci pour l'idée de requête, je vais travailler tout ça et je reviendrai ici poster mon avancée
    define: Programmeur : Celui qui résout un problème que vous n'aviez pas, d'une façon que vous ne comprenez pas.

  4. #4
    Membre averti Avatar de GyZmoO
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    428
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2006
    Messages : 428
    Points : 301
    Points
    301
    Par défaut
    Bonjour, bonjour.

    Après avoir suivi les conseils de CinePhil, j'ai modifié mes 2 tables R_A_MARQUE & R_A_PASSE de sorte à avoir une colonne représentant, respectivement le nombre de buts marqués & le nombre de passes réussies.

    Me suis dit chouette, à la place d'utiliser COUNT() je peux utiliser SUM !

    J'en suis arrivé à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT dom.TEAM_NAME, SUM(m1.r_a_marque_nb_td) as dom_score, ext.TEAM_NAME, SUM(m2.r_a_marque_nb_td) as ext_score
    FROM t_match m
    INNER JOIN t_team dom ON dom.team_id = m.match_team_domicile
    INNER JOIN t_player p_dom ON p_dom.player_team_id = dom.team_id
    INNER JOIN r_a_marque m1 ON m1.r_a_marque_player_id = p_dom.player_id
     
    INNER JOIN t_team ext ON ext.team_id = m.match_team_ext
    INNER JOIN t_player p_ext ON p_ext.player_team_id = ext.team_id
    INNER JOIN r_a_marque m2 ON m2.r_a_marque_player_id = p_ext.player_id
    Donc évidemment, cette requête ne donne pas le résultat attendu.

    A savoir que j'ai défini :

    3 players dans la team1 (joueur 1, joueur 2, joueur 3)
    3 players dans la team2 (joueur 21, joueur 22, joueur 23)
    Ensuite
    1 match auquel ont participé les teams 1 & 2.
    Et enfin,
    le joueur 1 a marqué deux but
    le joueur 2 a marqué un but
    le joueur 21 a marqué deux but

    Bref avec ce jeu de données de tests, je m'attends à avoir comme résultat
    Team1 - 3 - Team2 - 2
    Malheureusement j'ai ce résultat :

    Team1 - 3 - Team2 - 4
    Le score de l'équipe à l'extérieur est de 4 au lieu de 2.
    J'ai compris pourquoi, le résultat de la requête que j'ai donnée produit 2 lignes... Or y'a qu'un seul joueur qui a marqué pour la team2... Le 4 provient du fait que les 2 buts marqués par le joueur 21 sont comptés DEUX fois...

    Bref, j'ai du rater qq chose...

    De plus CinePhil, je me demandais, dans la requête que tu m'as montré, pourquoi utilises tu des jointures externes?

    Merci bien !!
    define: Programmeur : Celui qui résout un problème que vous n'aviez pas, d'une façon que vous ne comprenez pas.

  5. #5
    Membre averti Avatar de GyZmoO
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    428
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2006
    Messages : 428
    Points : 301
    Points
    301
    Par défaut
    De retour !

    Alors j'ai trouvé une requête qui répond à mes besoins :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    SELECT dom.TEAM_NAME, SUM(m1.r_a_marque_nb_td) AS dom_score, tmp.ext_name, tmp.ext_score
    FROM t_match m
    INNER JOIN t_team dom ON dom.team_id = m.match_team_domicile
    INNER JOIN t_player p_dom ON p_dom.player_team_id = dom.team_id
    INNER JOIN r_a_marque m1 ON m1.r_a_marque_player_id = p_dom.player_id
    INNER JOIN
    (SELECT ext.TEAM_NAME as ext_name, SUM(m2.r_a_marque_nb_td) AS ext_score, m.match_id
    FROM t_match m
    INNER JOIN t_team ext ON ext.team_id = m.match_team_ext
    INNER JOIN t_player p_ext ON p_ext.player_team_id = ext.team_id
    INNER JOIN r_a_marque m2 ON m2.r_a_marque_player_id = p_ext.player_id) tmp ON tmp.MATCH_ID = m.MATCH_ID
    Je ne sais pas si c'est une manière optimale, mais elle est fonctionnelle en tout cas

    J'en oublie la politesse : merci bien CinePhil tu m'as mis sur la piste !
    define: Programmeur : Celui qui résout un problème que vous n'aviez pas, d'une façon que vous ne comprenez pas.

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

Discussions similaires

  1. [MySQL] Chercher le contenu d'un tableau dans une table MySQL et jointure
    Par javagirl08 dans le forum PHP & Base de données
    Réponses: 13
    Dernier message: 19/08/2009, 13h40
  2. requete mysql vers jointure
    Par madjb dans le forum Requêtes
    Réponses: 1
    Dernier message: 22/07/2008, 18h32
  3. Jointure et groupement.
    Par tinmarbusir dans le forum Langage SQL
    Réponses: 8
    Dernier message: 21/02/2008, 11h24
  4. [MySQL] Plusieurs jointures sur une même table
    Par stephyyr dans le forum Langage SQL
    Réponses: 2
    Dernier message: 28/06/2006, 14h24
  5. Afficher une requete MYSQL avec jointure
    Par Higestromm dans le forum Requêtes
    Réponses: 8
    Dernier message: 18/12/2005, 15h52

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