Partage
  • Partager sur Facebook
  • Partager sur Twitter

COUNT() avec propre option

Sujet résolu
    15 septembre 2020 à 19:58:00

    Bonjour.

    Je n'arrive pas a passer les option que je souhaite a count.

    $req = $this->dao->prepare('
    SELECT posts.id,posts.elo, COUNT(calculation.id) AS rank, DATE_FORMAT(posts.date, "%d/%m/%y %H:%i") AS date
    FROM members, posts
    LEFT OUTER JOIN posts AS calculation ON calculation.elo > posts.elo
    ........ LIMIT 10



    Je voudrait recupérer le nombre de posts qui ont un elo supérieur au elo du SELECT en ignorant le limit.

    -
    Edité par -Crixus- 15 septembre 2020 à 20:03:20

    • Partager sur Facebook
    • Partager sur Twitter

    "Etre vrai, peu le peuvent."
    Friedrich Nietzsche

      15 septembre 2020 à 20:47:36

      Bonjour,

      Si j'ai bien compris ta question, et sans connaitre la structure exacte des tables, je proposerais :

      SELECT
      	P1.id,
      	P1.elo,
      	IF( P2.id IS NULL, 0, COUNT( * ) ) AS rank,
      	DATE_FORMAT( P1.date, "%d/%m/%y %H:%i") AS date,
      	M.?
      FROM
      	posts P1
      		INNER JOIN members M
      			ON P1.? = M.?
      		LEFT OUTER JOIN posts P2
      			ON P2.elo > P1.elo
      GROUP BY
      	P1.id,
      	P1.elo,
      	P1.date,
      	M.?
      ORDER BY rank DESC
      LIMIT 10

      Remplacer les ? par les bons noms de colonne ...

      Si je suis à côté de la plaque, merci de reformuler ou de donner des exemples précis de données et du résultat attendu ;)

      • Partager sur Facebook
      • Partager sur Twitter
      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
        15 septembre 2020 à 21:20:02

        Ouai.

        J'ai

        ID ELO
        1 | 500
        2 | 300
        3 | 600
        .. | ..
        500 | 500

        Je veut recuperer les 10 dernière id. Donc 491 a 500

        Pour chaque id je veux leur position (rank) qui se traduit par le nombre d'elo dans TOUTE la table > a l'elo de la ligne.

        Si dans ma selection des 10 dernier, le dernier l'id 500 a 0 de elo, que c'est l'elo le plus faible, et que le 499 a 2000 de elo et que c'est le plus fort je veux donc obtenir 10 ligne dont :

        id:500 | elo:0 | rank:500
        id:499 | elo:2000 | rank:1

        Il me semble que c'est un genre de self joint mais je suis pas sur. En tout cas mon code semble bancale.

        EDIT : J'avais oublier group by !!

        Ca marche mieux comme ca :

        $req = $this->dao->prepare('
        SELECT posts.id,posts.elo, COUNT(calculation.id) AS rank, DATE_FORMAT(posts.date, "%d/%m/%y %H:%i") AS date
        FROM members, posts
        LEFT OUTER JOIN posts AS calculation ON calculation.elo > posts.elo
        GROUP BY posts.id
        ........ LIMIT 10



        -
        Edité par -Crixus- 15 septembre 2020 à 21:55:46

        • Partager sur Facebook
        • Partager sur Twitter

        "Etre vrai, peu le peuvent."
        Friedrich Nietzsche

          15 septembre 2020 à 22:09:52

          Utiliser une fonction d'agrégation (ici SUM) sans GROUP BY c'est péché :D

          Au passage à quoi sert la table members si tu ne l'utilises pas, surtout sans jointure...

          Également, OUTER n'est pas nécessaire ici, cela l'était historiquement pour des raisons de compatibilité, genre il y a 10 ans ...

          Au final, ta requête est la même que la mienne sauf sur la clause ORDER BY où tu n'avais pas précisé l'ordre voulu dans ta question...

          Il faut vraiment que tu travailles la formulation de tes questions ... ;)

          -
          Edité par Benzouye 15 septembre 2020 à 22:12:22

          • Partager sur Facebook
          • Partager sur Twitter
          Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
            15 septembre 2020 à 23:33:19

            J'ai racourci la requète pour que vous puissiez la lire aisement.

                  $req = $this->dao->prepare('
                  SELECT posts.post, posts.id, posts.embed, posts.property, posts.link, posts.ranked, posts.elo, posts.subcategory, posts.country, COUNT(calculation.id) AS rank, DATE_FORMAT(posts.date, "%d/%m/%y %H:%i") AS date, posts_votes.id_vote AS idVote, members.id AS idMember, members.username, members.avatar, members.property AS avatarProperty 
                  FROM members, posts
                  LEFT JOIN posts_votes ON (posts_votes.id_post_winner = posts.id OR posts_votes.id_post_loser = posts.id) AND posts_votes.id_member=:sessionId
                  LEFT OUTER JOIN posts AS calculation ON calculation.elo > posts.elo AND calculation.subcategory = posts.subcategory AND calculation.ranked="1" 
                  WHERE
                  posts.ranked="1"
                  AND members.id=posts.id_member 
                  AND posts.category=:category
                  AND posts.country=:country
                  GROUP BY posts.id 
                  ORDER BY posts.elo DESC LIMIT 10

            Franchement je m'en sort pas mal niveau formulation. Le truc c'est qu'il faut regarder les codes que je poste. En fait j'aurai pu poster le code sans aucun autre commentaire et dire "pour quoi sa marche pas"... Après mon erreur ca a été justement de couper de code ce qui ne ta pas permit de voir que j'avais pas utiliser GROUP BY avec une function d'agrégat.

            Je dirais donc plutot... poste des code complet si tu veux qu'on t'aide. En tout cas, j'ai pas envie de croire que je m'exprime mal.

            Lol. Je me rapelerai "Utiliser une fonction d'agrégation (ici SUM) sans GROUP BY c'est péché" :)

            Merci d'être toujours présent.

            -
            Edité par -Crixus- 15 septembre 2020 à 23:35:52

            • Partager sur Facebook
            • Partager sur Twitter

            "Etre vrai, peu le peuvent."
            Friedrich Nietzsche

              16 septembre 2020 à 13:13:34

              Attention à l'utilisation du GROUP BY avec MySQL ... Un peu de lecture :

              http://cedric-duprez.developpez.com/tutoriels/mysql/demythifier-group-by/

              Sinon, évite de mélanger plusieurs syntaxes, notamment celles pour les jointures, c'est troublant et plus difficile à lire (cf. ma remarque sur ton autre sujet).

              Si l'on devait être rigoureux (indentation, jointure et alias), ta requête devrait s'écrire :

              SELECT
              	P.post,
              	P.id,
              	P.embed,
              	P.property,
              	P.link,
              	P.ranked,
              	P.elo,
              	P.subcategory,
              	P.country,
              	COUNT( C.id ) AS rank,
              	DATE_FORMAT( P.date, "%d/%m/%y %H:%i" ) AS date,
              	V.id_vote AS idVote,
              	M.id AS idMember,
              	M.username,
              	M.avatar,
              	M.property AS avatarProperty
              FROM
              	posts P
              		INNER JOIN members M
              			ON M.id = P.id_member
              		LEFT JOIN post_votes V
              			ON (
              				V.id_post_winner = P.id
              				OR V.id_post_loser = P.id
              			)
              			AND V.id_member = :sessionId
              		LEFT OUTER JOIN posts C
              			ON C.elo > P.elo
              			AND C.subcategory = P.subcategory
              			AND C.ranked = "1"
              WHERE
              	P.ranked="1"
              	AND P.category = :category
              	AND P.country = :country
              GROUP BY
              	P.post,
              	P.id,
              	P.embed,
              	P.property,
              	P.link,
              	P.ranked,
              	P.elo,
              	P.subcategory,
              	P.country,
              	P.date,
              	V.id_vote,
              	M.id,
              	M.username,
              	M.avatar,
              	M.property
              ORDER BY P.elo DESC
              LIMIT 10

              -
              Edité par Benzouye 16 septembre 2020 à 13:14:23

              • Partager sur Facebook
              • Partager sur Twitter
              Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                17 septembre 2020 à 13:16:02

                Si on stack les left join faut faire un select distinct non ? au moins sur le count :

                COUNT(DISTINCT C.id) AS rank

                J'ai pas bien compris pour quoi mais j'ai vu que ca stacké les données...

                -
                Edité par -Crixus- 17 septembre 2020 à 13:16:40

                • Partager sur Facebook
                • Partager sur Twitter

                "Etre vrai, peu le peuvent."
                Friedrich Nietzsche

                  17 septembre 2020 à 13:39:55

                  Cela va dépendre des cardinalités en jeu.

                  Le comportement de COUNT( DISTINCT ... ) est différent de COUNT( ... ) selon ces cardinalités.

                  Tu veux que je détaille ou suivre un cours MySQL te satisferait ? Cf. ma signature ;)

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL

                  COUNT() avec propre option

                  × 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