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 :

Petit souci sur le résultat d'une requête SELECT MySQL


Sujet :

Requêtes MySQL

  1. #1
    Futur Membre du Club
    Femme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mars 2023
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 22
    Localisation : France, Corse (Corse)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mars 2023
    Messages : 10
    Points : 8
    Points
    8
    Par défaut Petit souci sur le résultat d'une requête SELECT MySQL
    Bonjour tout le monde je demande votre aide à propos d'une requêtte select depuis plusiers tables(voir ci-dessous)

    le problème c'est que la jointure des trois table me donne des resultat dupliqués

    le resultat que je veux comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    1111 |  jean | lucas | CE1| Septembre |0.00|impayé|Septembre |0.00|impayé
    1111 |  jean | lucas | CE1| Octobre      |0.00|impayé|Octobre       |0.00|impayé
    1111 |  jean | lucas | CE1| novembre  |0.00|impayé|novembre   |0.00|impayé
    1111 |  jean | lucas | CE1| decembre   |0.00|impayé|decembre   |0.00|impayé
    1111 |  jean | lucas | CE1| janvier         |0.00|impayé|janvier         |0.00|impayé
    1111 |  jean | lucas | CE1| fevrier          |0.00|impayé|fevrier         |0.00|impayé
    1111 |  jean | lucas | CE1| mars            |0.00|impayé|mars            |0.00|impayé
    1111 |  jean | lucas | CE1| avril              |0.00|impayé|avril             |0.00|impayé
    1111 |  jean | lucas | CE1| mai              |0.00|impayé|mai               |0.00|impayé
    1111 |  jean | lucas | CE1| juin               |0.00|impayé|juin               |0.00|impayé
    j'ai essayé une jointure à la normal mais hélas elle me sorte chaque ligne dupliquée 10 fois

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT mt.massar,mt.nom,mt.prenom,mt.classe, ut.s_mois,ut.s_montant,ut.s_statut, ct.t_mois,ct.t_montant,ct.t_statut
    FROM
         etudiant mt
    INNER JOIN
         tb_spaiement ut on mt.massar = ut.massar
    LEFT JOIN 
         tb_tpaiement ct on mt.massar = ct.t_massar
    WHERE 
         mt.massar = '1111'

    Ma table Etudiant:
    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
     
    CREATE TABLE `etudiant` (
      `id` int(11) NOT NULL,
      `massar` varchar(20) NOT NULL,
      `nom` varchar(30) NOT NULL,
      `prenom` varchar(30) NOT NULL,
      `classe` varchar(30) NOT NULL,
      `transport` varchar(30) NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
     
    --
    -- Déchargement des données de la table `etudiant`
    --
     
    INSERT INTO `etudiant` (`id`, `massar`, `nom`, `prenom`, `classe`, `transport`) VALUES
    (1, '1111', 'jean', 'lucas', 'CE1', 'oui');
    Ma table tb_spaiement:
    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
     
    CREATE TABLE `tb_spaiement` (
      `id` int(11) NOT NULL,
      `massar` varchar(20) DEFAULT NULL,
      `s_mois` varchar(20) DEFAULT NULL,
      `s_montant` decimal(8,2) NOT NULL,
      `s_statut` varchar(20) DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
     
    --
    -- Déchargement des données de la table `tb_spaiement`
    --
     
    INSERT INTO `tb_spaiement` (`id`, `massar`, `s_mois`, `s_montant`, `s_statut`) VALUES
    (1, '1111', 'Septembre', '0.00', 'Impayé'),
    (2, '1111', 'Octobre', '0.00', 'Impayé'),
    (3, '1111', 'Novembre', '0.00', 'Impayé'),
    (4, '1111', 'Décembre', '0.00', 'Impayé'),
    (5, '1111', 'Janvier', '0.00', 'Impayé'),
    (6, '1111', 'Février', '0.00', 'Impayé'),
    (7, '1111', 'Mars', '0.00', 'Impayé'),
    (8, '1111', 'Avril', '0.00', 'Impayé'),
    (9, '1111', 'Mai', '0.00', 'Impayé'),
    (10, '1111', 'Juin', '0.00', 'Impayé');
    ma table tb_tpaiement :

    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
     
    CREATE TABLE `tb_tpaiement` (
      `id` int(11) NOT NULL,
      `t_massar` varchar(20) NOT NULL,
      `t_mois` varchar(20) DEFAULT NULL,
      `t_montant` decimal(8,2) NOT NULL,
      `t_statut` varchar(20) DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
     
    --
    -- Déchargement des données de la table `tb_tpaiement`
    --
     
    INSERT INTO `tb_tpaiement` (`id`, `t_massar`, `t_mois`, `t_montant`, `t_statut`) VALUES
    (1, '1111', 'Septembre', '0.00', 'Impayé'),
    (2, '1111', 'Octobre', '0.00', 'Impayé'),
    (3, '1111', 'Novembre', '0.00', 'Impayé'),
    (4, '1111', 'Décembre', '0.00', 'Impayé'),
    (5, '1111', 'Janvier', '0.00', 'Impayé'),
    (6, '1111', 'Février', '0.00', 'Impayé'),
    (7, '1111', 'Mars', '0.00', 'Impayé'),
    (8, '1111', 'Avril', '0.00', 'Impayé'),
    (9, '1111', 'Mai', '0.00', 'Impayé'),
    (10, '1111', 'Juin', '0.00', 'Impayé');

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Bonjour,
    Pour moi il manque le mois dans la jointure entre les tables tb_tpaiement et tb_spaiement.

    Mais je pense surtout que le modèle est à revoir.
    Pour moi la requête devrait ressembler à ceci:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT mt.massar,mt.nom,mt.prenom,mt.classe, ut.s_mois,ut.s_montant,ut.s_statut, ct.t_mois,ct.t_montant,ct.t_statut
    FROM
         etudiant mt
    INNER JOIN
         tb_spaiement ut on mt.id = ut.id_etudiant
    LEFT JOIN 
         tb_tpaiement ct on mt.id = ct.id_etudiant and ct.id_paiement = ut.id
    WHERE 
         mt.massar = '1111'

    Tatayo.

  3. #3
    Futur Membre du Club
    Femme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mars 2023
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 22
    Localisation : France, Corse (Corse)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mars 2023
    Messages : 10
    Points : 8
    Points
    8
    Par défaut
    Merci Tatayo pour votre temps consacré, mais votre requête m'as donné une erreur :

    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
     
    Erreur
    Requête SQL : Copier Documentation
     
     
    SELECT mt.massar,mt.nom,mt.prenom,mt.classe, ut.s_mois,ut.s_montant,ut.s_statut, ct.t_mois,ct.t_montant,ct.t_statut
    FROM
         etudiant mt
    INNER JOIN
         tb_spaiement ut on mt.id = ut.id_etudiant
    LEFT JOIN 
         tb_tpaiement ct on mt.id = ct.id_etudiant and ct.id_paiement = ut.id
    WHERE 
         mt.massar = '1111' LIMIT 0, 25
    MySQL a répondu : Documentation
     
    #1054 - Champ 'ut.id_etudiant' inconnu dans on clause

  4. #4
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    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 : 10 136
    Points : 38 910
    Points
    38 910
    Billets dans le blog
    9
    Par défaut
    Bonjour,

    Il est préférable de créer des colonnes mois de type char(02) et de stocker les valeurs sous la forme '01' (janvier) à '12' (décembre) en positionnant une contrainte de type CHECK pour vérifier que les valeurs sont bien comprises entre '01' et '12' plutôt que de stocker des mois sous la forme de libellés.
    D'une part ce sera moins encombrant, et plus performant, d'autre part les libellés sont sensibles à la collation (combinaisons de majuscules/minuscules, caractères diacritiques et ligatures). Ce faisant, le résultat des comparaison d'une table à l'autre peut varier en fonction de la collation !

    Également, il est manque probablement une contrainte d'unicité sur le coupe étudiant + mois dans la table tb_spaiement, car en l'état, vous pouvez insérer plusieurs lignes pour un même étudiant et un même mois, à vérifier.

    Et aussi, le type decimal(8,2) a le même encombrement que le decimal(9,2), il n'y a donc pas d'intérêt à choisir du decimal(8,2)
    Voir la documentation MySQL à ce propos ICI

    Et la preuve par l'exemple ci-dessous :

    Code SQL : 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
    create table T1
          (  T1ID    integer       primary key
           , T1D82   decimal(8,2)  not null
           , T1D92   decimal(9,2)  not null
          )
    ;
    insert into T1 (T1ID, T1D82, T1D92)
    values (1, 123456.78, 123456.78)
         , (2, 999999.99, 999999.99)
    ;
    select T1ID          as  "Ident"
         , T1D82         as  "D(8,2)"
         , T1D82 + 0.1   as  "D(8,2)+0,1"
         , T1D92         as  "D(9,2)"
         , T1D92 + 0.1   as  "D(9,2)+0,1"
    from T1
    ;

    Résultat :

    Nom : Sans titre.png
Affichages : 72
Taille : 4,1 Ko

    Autre point, pourquoi mettre des commentaires tels que "Déchargement des données de la table `etudiant" alors qu'on fait des INSERT dans cette table, et donc un chargement ?
    Tant qu'à mettre des commentaires, autant qu'ils correspondent à la réalité

    Enfin et surtout, pour répondre à votre question sur l'erreur de jointure, comme il n'y a aucune contrainte de type "FOREIGN KEY" dans vos tables, on ne sait pas comment faire correctement les jointures.
    L'absence de contraintes FK est ce qu'il y a de pire dans votre modèle de données, car sans contrainte FK, il n'y a aucune garantie d'intégrité de vos données

    EDIT : je vois qu'il n'y a pas non plus de contrainte PRIMARY KEY, autre défaut majeur !

  5. #5
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    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 : 10 136
    Points : 38 910
    Points
    38 910
    Billets dans le blog
    9
    Par défaut
    Voici un exemple de ce que devrait être le script de création de vos tables en tenant compte des éléments suivants :
    • les quotes inversées autour des noms d'objets sont inutiles quand ces noms ne sont pas des mots réservés SQL ;
    • toute table doit avoir une PK, cette PK doit être consise (performances) et surtout stable en contenu d'où le choix d'un identifiant technique.
      le plus souvent, on utilise une colonne dont la valeur est attribuée par le SGBD, c'est à dire, pour MYSQL, un AUTO_INCREMENT ;
    • toute colonne faisant référence à une PK doit faire l'objet d'une contrainte FK ;
    • pour faciliter la compréhension, quand une colonne est FK, on conserve le même nom que là où elle est PK ;
    • le mois est stocké par numéro et non par libellé, avec une contrainte check pour en contrôler la valeur;
    • la classe ne dépend pas fonctionnellement de l'étudiant, on crée donc une table des classes et, dans la table étudiant, on ajoute un FK faisant référence à l'identifiant de la classe.


    Code SQL : 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
    CREATE TABLE CLS_classe
         (  CLS_ident    integer      primary key
          , CLS_code     char(4)      unique
          , CLS_nom      varchar(30)  not null
         ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
    ;
    CREATE TABLE ETU_etudiant
         (  ETU_ident    integer      primary key
          , ETU_nom      varchar(30)  not null
          , ETU_prenom   varchar(30)  not null
          , CLS_ident    integer      not null
          , constraint ETUFK1  
            foreign key (CLS_ident) 
            references CLS_classe(CLS_ident)
         ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
    ;
    CREATE TABLE SPM_spaiement
         (  ETU_ident    integer      not null
          , SPM_mois     char(02)     not null
          , SPM_montant  decimal(9,2) not null
          , primary key (ETU_ident, SPM_mois)
          , constraint SPMFK1  
            foreign key (ETU_ident) 
            references ETU_etudiant(ETU_ident)
          , constraint SPMCH1 CHECK (SPM_mois between '01' and '12'
         ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci
    ;
    CREATE TABLE etc. À compléter

    Il peut y avoir quelques coquilles vu que j'ai créé ce script de toutes pièces, mais l'idée est là

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 198
    Points : 12 774
    Points
    12 774
    Par défaut
    Citation Envoyé par michou2001 Voir le message
    Merci tatayo pour votre temps consacré votre requette m'as donnée une erreur :
    #1054 - Champ 'ut.id_etudiant' inconnu dans on clause
    C'est normal, je disais que la requête devrait ressembler à ça, si on "corrige" la structure des tables.
    Dans ton schéma li n'y a aucune clé étrangère…

    Donc si on garde les tables telles qu'elles sont (pas bien !):
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT mt.massar,mt.nom,mt.prenom,mt.classe, ut.s_mois,ut.s_montant,ut.s_statut, ct.t_mois,ct.t_montant,ct.t_statut
    FROM
         etudiant mt
    INNER JOIN
         tb_spaiement ut on mt.massar = ut.massar
    LEFT JOIN 
         tb_tpaiement ct on mt.massar = ct.t_massar and ut.s_mois = ct.t_mois
    WHERE 
         mt.massar = '1111'

    Tatayo.

  7. #7
    Futur Membre du Club
    Femme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mars 2023
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 22
    Localisation : France, Corse (Corse)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mars 2023
    Messages : 10
    Points : 8
    Points
    8
    Par défaut
    merci beacoup messieurs tatayo et escartefigue je suivrait à la lettre vos insructions et désolé pour ma lente compréhension je suis encore débutante je crois que je devrait réviser mes leçons en premier

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

Discussions similaires

  1. [MySQL-3.23] Petit souci sur une requête UPDATE un peu compliquée
    Par emilie93 dans le forum Requêtes
    Réponses: 10
    Dernier message: 09/01/2023, 22h30
  2. [XL-2007] Petit soucis sur une macro comportant un "For"
    Par Arkadian dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 01/07/2015, 17h56
  3. Réponses: 11
    Dernier message: 07/04/2010, 17h51
  4. Petit souci sur une boucle PHP
    Par ns_deux dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 1
    Dernier message: 30/03/2009, 20h31
  5. Petit souci sur la libération d'une connexion tcp
    Par alexandre75 dans le forum Développement
    Réponses: 1
    Dernier message: 08/11/2005, 19h43

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