Partage
  • Partager sur Facebook
  • Partager sur Twitter

Récupérer une valeur COUNT pour l'utiliser dans le WHERE.

Sujet résolu
    10 septembre 2011 à 12:42:04

    Bonjour, je souhaite faire la requête suivante:

    Récupérer toutes les lignes qui ont plus d'une IP enregistrée et dont la clé d'activation est différente de 'vide'.

    SELECT COUNT(ID_IP) as nb_ip, CLE_ACTIVATION FROM ip_personne NATURAL JOIN personne WHERE CLE_ACTIVATION!='' AND nb_ip > 1;
    


    Mais MySQL me répond ceci:

    Unknown column 'nb_ip' in 'where clause'.

    Edit: Trouvé. Il fallait faire un select dans un select.

    SELECT  * FROM ip_personne NATURAL JOIN personne WHERE CLE_ACTIVATION!='' AND (SELECT COUNT(ID_IP) FROM ip_personne) > 1;
    


    Pourquoi ? Dois-je faire autrement ?

    Merci.
    • Partager sur Facebook
    • Partager sur Twitter
      10 septembre 2011 à 13:43:48

      Je pense que tu peux faire autrement :
      SELECT COUNT(id_personne.ID_IP) as nb_ip, personne.CLE_ACTIVATION 
      FROM ip_personne NATURAL JOIN personne 
      WHERE personne.CLE_ACTIVATION!='' -- AND nb_ip > 1;
      GROUP BY personne.CLE_ACTIVATION
      HAVING COUNT(id_personne.ID_IP) > 1;
      


      • Partager sur Facebook
      • Partager sur Twitter
        10 septembre 2011 à 17:28:42

        Merci, je testerai pour voir les différences d'exécution.
        • Partager sur Facebook
        • Partager sur Twitter
          13 septembre 2011 à 21:21:43

          Alors, est-ce que ça fonctionne comme tu veux ?
          • Partager sur Facebook
          • Partager sur Twitter
            14 septembre 2011 à 10:31:05

            La mienne fonctionne tandis que la tienne ne donne pas de résultat.

            Comme la mienne semblait fonctionner correctement j'ai pas été chercher plus loin ^^

            ;)
            • Partager sur Facebook
            • Partager sur Twitter
              14 septembre 2011 à 10:53:12

              Peux-être qu'il ne faut pas passer par le NATURAL JOIN.

              SELECT COUNT(IDP.ID_IP) AS nb_ip, P.CLE_ACTIVATION 
              FROM ip_personne IDP
              INNER JOIN personne P
              ON IDP.id_personne = P.id_personne -- id_personne -> dépend de ce que tu as mis comme nom pour la clé
              WHERE P.CLE_ACTIVATION!='' 
              GROUP BY P.CLE_ACTIVATION
              HAVING COUNT(IDP.ID_IP) > 1;
              


              Essaye ceci dans la commande SQL pour voir ce que cela te retourne.
              • Partager sur Facebook
              • Partager sur Twitter
                14 septembre 2011 à 19:10:33

                Oui mais attention, si cela ne retourne aucun résultat, cela peut tout simplement dire que il n'y a pas plusieurs même clé d'activation plus d'un IP.
                Il faut tester avec une table ayant une clé avec différents IP.
                • Partager sur Facebook
                • Partager sur Twitter
                  14 septembre 2011 à 19:34:42

                  Yep, c'est bien sûr ce que je fais (sinon ce serait vraiment te faire tourner en bourrique !).

                  Bah t'embêtes pas plus, ça fonctionne correctement avec la mienne et je pense qu'elle est plus rapide qu'avec un having (et puis pour 0.00002 s... ^^)
                  • Partager sur Facebook
                  • Partager sur Twitter
                    14 septembre 2011 à 21:52:25

                    Citation : Mini Vado

                    ça fonctionne correctement avec la mienne et je pense qu'elle est plus rapide qu'avec un having (et puis pour 0.00002 s... ^^)


                    J'aimerais bien savoir comment tu es arrivé à une telle conclusion, en sachant que tu ne peux pas utiliser de HAVING sans clause GROUP BY. Ta requête ne fait que retourner les lignes s'il n'y en a au moins deux non nulles. L'utilité me paraît quand même très discutable.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      15 septembre 2011 à 0:36:52

                      J'utilise pas having.

                      Ma requête me retourne les lignes n'ayant pas de chaine vide à CLE_ACTIVATION et dont le nombre d'IP enregistrées est supérieur à 1.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        15 septembre 2011 à 2:27:24

                        Si tu parles de la requête dans ton premier post :

                        Citation : Mini Vado

                        SELECT * 
                        FROM ip_personne 
                        NATURAL JOIN personne
                        WHERE CLE_ACTIVATION != '' 
                          AND (SELECT COUNT(ID_IP) FROM ip_personne) > 1;
                        

                        Ta requête retourne les lignes n'ayant pas de chaîne vide à CLÉ_ACTIVATION (pourquoi ne pas y mettre NULL alors ?) et si le nombre TOTAL de ID_IP dans la table ip_personne est plus grand que 1. C'est très différent de ce que tu décris. Essentiellement, SELECT COUNT(ID_IP) FROM ip_personne est calculé une seule fois et si la condition est vraie pour une ligne, elle l'est pour toutes les lignes. Bref, relativement inutile.

                        Citation

                        J'utilise pas having.


                        Alors comment fais-tu pour conclure qu'elle est plus rapide ?

                        P.S. L'opérateur d'inégalité en SQL, c'est de préférence (selon la norme) <> et non !=.
                        • Partager sur Facebook
                        • Partager sur Twitter
                          15 septembre 2011 à 13:19:12

                          Désolé mais j'arrive pas à comprendre la différence.

                          Pour le NULL, non car je met manuellement la valeur à "vide".

                          je conclu pas, je pense et donc je peux me tromper, sa requête ne fonctionnant pas je peux pas avoir la valeur d'exécution de mysql.

                          Et merci pour le signe, le != fonctionnant bien (habitué à php, c#, ..) j'ai même pas pensé à <>
                          • Partager sur Facebook
                          • Partager sur Twitter
                            15 septembre 2011 à 19:00:54

                            La différence est que tu veux apparemment les lignes uniquement si l'adresse IP correspondante (celle de la ligne) est en double. Ta requête te retourne essentiellement toutes les adresses IP (où CLE_ACTIVATION est une chaîne vide).

                            Citation

                            Pour le NULL, non car je met manuellement la valeur à "vide".


                            Je vois pas le rapport. Une chaîne vide est une information, NULL est l'absence d'une information.
                            • Partager sur Facebook
                            • Partager sur Twitter
                              15 septembre 2011 à 20:58:26

                              Y a quiprocquo sur le NULL.
                              La clé une fois validée vaut '' donc "vide" mais pas NULL.
                              Donc je teste sur "" (vide). Logique.

                              ma requête me retourne toutes les personnes n'ayant pas activé leur compte et dont l'IP est déjà référencé.
                              Et c'est exactement ce que je veux.
                              • Partager sur Facebook
                              • Partager sur Twitter
                              Anonyme
                                16 septembre 2011 à 20:35:56

                                "" == NULL ^^

                                Fayden essaye de te l'expliqué..
                                • Partager sur Facebook
                                • Partager sur Twitter
                                Anonyme
                                  16 septembre 2011 à 20:46:34

                                  Citation : Alv4rd

                                  "" == NULL ^^



                                  En fait, il dit (à raison) exactement le contraire :

                                  Citation : Fayden

                                  Une chaîne vide est une information, NULL est l'absence d'une information.

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                  Anonyme
                                    16 septembre 2011 à 20:50:39

                                    Citation : Enax

                                    Citation : Alv4rd

                                    "" == NULL ^^



                                    En fait, il dit (à raison) exactement le contraire :

                                    Citation : Fayden

                                    Une chaîne vide est une information, NULL est l'absence d'une information.



                                    Autant pour moi ^^:JeSort:
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      16 septembre 2011 à 22:55:14

                                      Citation : Mini Vado

                                      Donc je teste sur "" (vide). Logique.


                                      Je n'ai pas dit que ce que tu fais ne fonctionne pas, je questionne ton choix d'utiliser une chaîne vide pour marquer quelque chose qui n'existe pas.

                                      Citation : Mini Vado

                                      ma requête me retourne toutes les personnes n'ayant pas activé leur compte et dont l'IP est déjà référencé.


                                      Ta requête retourne toutes les personnes n'ayant pas activé leur compte, point. Ton autre condition est toujours vraie. Un exemple devrait te faire comprendre un peu ce que j'essaie de te dire :

                                      fayden=> SELECT * FROM test_ip;
                                             ip        
                                      -----------------
                                       127.0.0.1
                                       123.123.123.123
                                       127.0.0.1
                                       0.0.0.0
                                       0.0.0.0
                                      (5 lignes)
                                      
                                      fayden=> SELECT * FROM test_ip WHERE (SELECT COUNT(ip) FROM test_ip) > 1;
                                             ip        
                                      -----------------
                                       127.0.0.1
                                       123.123.123.123
                                       127.0.0.1
                                       0.0.0.0
                                       0.0.0.0
                                      (5 lignes)
                                      
                                      fayden=> SELECT * FROM test_ip GROUP BY ip HAVING COUNT(*) > 1;
                                          ip     
                                      -----------
                                       127.0.0.1
                                       0.0.0.0

                                      Comme tu le vois, la deuxième requête retourne toutes les lignes dans ta table. C'est normal, il y en a 5 et 5 est plus grand que 1. La deuxième retourne uniquement les lignes où les adresses IP sont en doubles.

                                      Ce que tu recherches semble plutôt être ceci :
                                      SELECT nom_personne
                                      FROM ip_personne
                                      NATURAL JOIN personne
                                      WHERE CLE_ACTIVATION <> ''
                                      GROUP BY nom_personne
                                      HAVING COUNT(ID_IP) > 1;
                                      

                                      Toutefois, j'ai repris en gros ta requête, mais ça ne semble toujours pas correspondre à ta description en français. Celle-ci sélectionne toutes les lignes où CLE_ACTIVATION est différente d'une chaîne vide et il y a au moins deux adresses IP correspondantes dans la table ip_personne. Pourquoi avoir au moins deux adresses IP pour conclure que l'IP est déjà référencée ? Bref, en me basant uniquement sur ta description en français, la requête que tu recherches, c'est celle-ci :

                                      SELECT nom_personne
                                      FROM personne p
                                      LEFT OUTER JOIN ip_personne i
                                          ON p.id_personne = i.id_personne
                                      WHERE i.id_personne IS NULL
                                        AND CLE_ACTIVATION <> '';
                                      


                                      P.S. Je maintiens toujours qu'il vaudrait mieux que CLE_ACTIVATION soit NULL.
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        17 septembre 2011 à 2:26:43

                                        je viens de tester ta requête SQL.

                                        SELECT nom_personne
                                        FROM ip_personne
                                        NATURAL JOIN personne
                                        WHERE CLE_ACTIVATION <> ''
                                        GROUP BY nom_personne
                                        HAVING COUNT(ID_IP) >= 1;
                                        


                                        (Au passage c'était supérieur ou égal, bien vu)
                                        Et elle me rapporte autant de résultats que celle que j'avais faite. Pas la moindre différence.

                                        Pourquoi vaut il mieux NULL que vide ?

                                        La tienne en 0.0018sec.
                                        La mienne en 0.0018sec.

                                        Merci de ton aide en tout cas. Peut-être ais-je une configuration spécifique qui fait que dans mon cas les deux fonctionnent alors que la première ne devrait donner le résultat attendu.
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          17 septembre 2011 à 2:34:12

                                          Citation : Mini Vado

                                          Et elle me rapporte autant de résultats que celle que j'avais faite. Pas la moindre différence.


                                          Probablement parce que tous tes comptes ont au moins une adresse IP correspondante. Essaie d'ajouter manuellement une ligne dans la table personne sans mettre de ligne correspondante dans la table ip_personne, tu te rendras compte que ta requête la renverra alors que la mienne, non.

                                          Citation : Mini Vado

                                          Pourquoi vaut il mieux NULL que vide ?


                                          Parce qu'une chaîne vide est une valeur, alors que tu veux marquer l'absence de valeur. Conceptuellement, c'est NULL qui est le plus approprié, même si tu peux faire autrement. Côté requêtes, comme une chaîne vide est une valeur, les fonctions d'agrégat (MIN par exemple) agiront de façon non attendue. Dans le cas d'une chaîne, c'est moins fréquent, mais imagine que tu aies une colonne de type integer et que tu mettes la valeur -1 ou 0 qui ne correspond à rien. Tu ne peux plus utiliser les fonctions AVG, MIN, MAX, etc. sur cette colonne parce que le fait d'avoir une valeur (-1 ou 0) change tout. Si tu mets NULL, les fonctions d'agrégat ignore les lignes où la colonne vaut NULL.
                                          Ensuite, NULL prendra probablement moins de place qu'une chaîne vide, mais bon, ça ne pose pas vraiment problème avec les disques durs d'aujourd'hui.
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            17 septembre 2011 à 10:55:49

                                            En effet car je stocke l'IP de l'inscription.

                                            Merci pour l'explication, ça m'évitera de faire des conneries à l'avenir.
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              17 septembre 2011 à 15:21:55

                                              Un IP change 1 fois tout les 1 à 2 ans en moyenne en fonction du FAI.
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                17 septembre 2011 à 18:51:52

                                                Sauf si elle est modifiée manuellement...
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  19 septembre 2011 à 10:15:06

                                                  Non, tu auras beau changer ton adresse IP manuellement, l'IP qui sortira derrière ton modem sera le même pendant 1 ou 2 ans.
                                                  Enfin normalement.
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter

                                                  Récupérer une valeur COUNT pour l'utiliser dans le WHERE.

                                                  × 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