Partage
  • Partager sur Facebook
  • Partager sur Twitter

[MySQL] Renvoi mauvaises valeurs

Parce que mauvaise requête, je sais :p

Sujet résolu
    25 juin 2019 à 16:16:55

    Bonjour à vous,

    J'ai une base, avec 2 tables : users et associations.

    Dans la table users, j'ai 2 utilisateurs et une catégorie "association_id" où j'y stocke l'id de l'association de la table éponyme.

    Donc si je compte :

    - le nombre d'utilisateurs -> 2 

    - le nombre d'association -> 1 PROBLEME:MySQL m'en sort 2 (il doit me compter une association par utilisateur)

    Voici ma requête :

    SELECT COUNT(associations.id) as nbAsso, COUNT(users.id) as nbUser 
    FROM users, associations 
    WHERE users.id_association IS NOT NULL

    Ma requête demande aussi d'autres infos sur d'autres tables, mais à chaque fois, il me le fait par utilisateurs. Donc j'ai des valeurs multiplié par le nombre d'utilisateurs.

    Je me doute du problème, mais je ne vois pas comment le résoudre sans devoir faire 2 requêtes séparées.

    Je vous remercie pour votre aide.



    -
    Edité par PimpreneIIe 25 juin 2019 à 16:18:45

    • Partager sur Facebook
    • Partager sur Twitter
      25 juin 2019 à 18:07:19

      Bonjour,

      Ta question prouve que tu n'as pas ne serait-ce que démarré un cours sur le SQL ... Je te conseille fortement la lecture du cours MySQL de OpenClassrooms (cf. ma signature) avant d'aller plus loin ...

      Ta requête n'a pas de jointure et te retourne 2 enregistrements parce que tu n'as qu'une seule association d'enregistrée ... Si tu rajoutes une association dans la table associations, ta requête va te retourner 4 ...

      Donc première leçon à intégrer : les jointures ...

      PimpreneIIe a écrit:

      il doit me compter une association par utilisateur

      Oui, et c'est le comportement normal du SQL ... Tu ne comptes pas le nombre d'associations, mais le nombre d'enregistrements retournés par ta requête ...

      Pour comprendre pourquoi la requête te retourne 2, fait ceci :

      SELECT *
      FROM users, associations
      WHERE users.id_association IS NOT NULL

      PimpreneIIe a écrit:

      je ne vois pas comment le résoudre sans devoir faire 2 requêtes séparées

      Donc deuxième leçon à intégrer : les agrégats ... et l'utilisation de DISTINCT ...

      Par ailleurs, il faut espérer qu'un utilisateur ne puisse être dans plusieurs associations à la fois ... moi personnellement je suis adhérents de 3 associations ...

      Globalement, il faut vraiment suivre le cours qui répondra à ce genre de questions basiques et te permettra de prendre de bonnes habitudes ;)

      -
      Edité par Benzouye 25 juin 2019 à 18:09:26

      • Partager sur Facebook
      • Partager sur Twitter
      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
        1 juillet 2019 à 13:30:51

        Bonjour,

        J'avais réalisé le cours "Concevez votre site web avec PHP et MySQL".

        En tout cas, je connais déjà la réponse pour cette requête. (Surtout l'utilisation de DISTINCT)

        Cependant j'espérais une autre réponse qui aurait résolu le problème de ma requête complète (que j'avais volontairement simplifié, pensant que ça suffirait).

        En effet j'ai une 3ème table "historics" avec des transactions entre utilisateurs et associations.

        Afin d'avoir un tableau de bord avec plusieurs indicateurs, je cherche à avoir :

        - nombre d'asso
        - nombre d'utilisateur
        - la consommation mensuelle de tous les utilisateurs
        - les crédits dans leur solde qui n'ont pas encore été utilisés
        - la somme totale des crédits utilisés

        Ma requête ressemble à ça :

        SELECT COUNT(DISTINCT associations.id) as nbAsso, COUNT(DISTINCT users.id) as nbUser, SUM(historics.amount) as monthConsoUsers, SUM(associations.solde + users.solde) as noConsumed
        FROM users 
        INNER JOIN associations
        ON users.id_association = associations.id 
        LEFT JOIN historics
        ON users.id = historics.id_user AND users.id_association = historics.id_association
        WHERE users.id_association IS NOT NULL AND historics.type='utilisation' AND historics.date >= NOW() - interval 1 month

        nbAsso : Je compte les id des associations de ma table association (mais si je n'ai pas d'utilisateurs de l'asso, je ne vois pas toutes les asso....)

        nbUser : le plus facile, je compte les id de la table "users"

        monthConsoUsers : La somme de mes transactions avec le "type" qui est égale à "utilisation". Comme j'utilise cette condition dans mon WHERE, j’exclus pleins de résultats qui me servent pour mes autres besoins....

        noConsumed : Les asso et les users ont des soldes qu'ils peuvent dépenser. Ce sont les crédits encore non utilisés. Je devrais les sommer pour avoir l'indicateur voulu.

        allAmount : non présent ici, mais c'est comme monthConsoUsers mais sans la condition temporelle

        Je vais refaire le cours pour voir si je trouve tout seul les réponses !



        -
        Edité par PimpreneIIe 1 juillet 2019 à 14:59:15

        • Partager sur Facebook
        • Partager sur Twitter
          3 juillet 2019 à 15:21:23

          Je pense que tu essayes de faire trop de choses dans la même requête.

          Si un utilisateur a plusieurs "historics", alors il va apparaître sur plusieurs lignes et son "association" aussi. Les deux champs suivants vont compter des lignes en doublon :

          SUM(historics.amount) as monthConsoUsers, SUM(associations.solde + users.solde) as noConsumed

          Par exemple users.solde sera compté plusieurs fois dans noConsumed.

          Conclusion : fais plusieurs requêtes en ciblant bien ce que tu veux à chaque fois.

          • Partager sur Facebook
          • Partager sur Twitter
            9 juillet 2019 à 12:25:48

            D'accord, merci =) Je dois faire plusieurs requêtes.
            • Partager sur Facebook
            • Partager sur Twitter

            [MySQL] Renvoi mauvaises valeurs

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown