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

PHP & Base de données Discussion :

Count et Group by et Order by en conflit. Un bug ou normal ?


Sujet :

PHP & Base de données

  1. #1
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut Count et Group by et Order by en conflit. Un bug ou normal ?
    Salut

    Je vous fais part d'un phénomène qui me parais plutôt étrange sur une banale petite requête où le ORDER BY serait entre autre l'acteur principal.

    La requête à l'origine : (c'est un système de ticket interne)
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT COUNT(*) AS total
    FROM ticket t
    JOIN ticket_history th ON t.ticket_id = th.ticket_id
    JOIN ticket_status ts ON t.status_id = ts.status_id
    WHERE t.users_id = 100
    AND th.publier = 1
    AND t.status_id = 1
    GROUP BY t.ticket_id
    ORDER BY t.date_created DESC
    LIMIT 1
    Cette requête retourne 2 pour "total", MySQL trouve donc 2 lignes.
    Or, je sais qu'il y en a 3.
    -> 1 ligne ticket_id pour le user_id 100 dans la table ticket
    -> 3 lignes ticket_id dans la table ticket_history (3 réponses).


    Je supprime dans la requête le ORDER BY (ORDER BY t.date_created DESC), et hop, cette fois MySQL trouve bien les 3 lignes.
    Depuis quand un ORDER BY agirait sur le nombre de ligne à retourner ?


    Personnellement je le trouve un peu fort l'café, même ici le ORDER BY n'était pas utile.


    Selon vous, c'est normal ou pas ?
    Une explication serait le bienvenu.
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  2. #2
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Points : 1 565
    Points
    1 565
    Par défaut
    Bonjour,

    moi ce qui me perturbe c'est le LIMIT 1 a la fin.
    Si tu lui dit que tu veux un seul resultat, pourquoi il t'en retourne 2 (ou 3) ?

    peut etre que mysql tri la table en interne pour réaliser le group by et que ton order by "perturbe" ce tri.

    Essaye un order by par la meme colonne que la colonne de group by pour voir ?

  3. #3
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    moi ce qui me perturbe c'est le LIMIT 1 a la fin.
    Si tu lui dit que tu veux un seul resultat, pourquoi il t'en retourne 2 (ou 3) ?
    Je ne souhaite pas que ça retourne les lignes, je veux juste connaitre le nombre de lignes de ticket_history, le nombre de réponses en faite.
    D'où le COUNT(*), et d'où le LIMIT 1.

    Mais effectivement, j'avais déjà fait cet essai de supprimer le LIMIT 1, ça n'a rien changé au résultat du total, du COUNT(*).

    Citation Envoyé par Fladnag
    Essaye un order by par la meme colonne que la colonne de group by pour voir ?
    C'est exactement ça qui perturbe la requête.
    En faite, faut pas que ça soit la même colonne que le Group by, du moins apparemment.

    Si je met un tri sur la table ticket_history, ça compte bien 3 (c'est bon).
    Mais dès que c'est un champ de la table ticket, ça compte 2.


    C'est terrible ça.
    Alors là, c'est la 1ère fois que je remarque ça.

    Mais franchement, c'est normal ou pas ?
    Bug ou pas bug ?
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  4. #4
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Points : 1 565
    Points
    1 565
    Par défaut
    ok pour le limit, en effet ^^ mais il ne sert a rien lui non plus je pense.

    normal ? A priori je dirais non
    bug ? a priori je dirais oui

    Mais bon, les parseurs de SGBD sont super compliqués donc l'explication est peut etre a trouver dans le cas d'une requete super compliquée pour laquelle on a besoin de ce truc.

    Essaye de faire un POC (Proof Of Concept) avec des tables, des champs et des données simples et remonte le a Mysql ;o)

    Sinon il n'y a pas de champs NULL dans tes tables ?

  5. #5
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Sinon il n'y a pas de champs NULL dans tes tables ?
    Il se trouve que non, tout est obligatoire, de plus que du classique coté type de données, et visuellement ça à l'air correcte.

    Mais ce qui devient de plus en plus étrange, voir même plus inquiétant, c'est que je ne parviens pas à reproduire l'erreur.
    Vite fait comme ça, j'ai créer une autre Bdd, tables ... et fait quelques essais des plus basiques avec les fonctions mysql_*.
    Et là, avec ou sans ORDER BY, ou de LIMIT, tout est cohérent.

    Vu que dans le projet en question j'utilise PDO, abstraction et tunti quanti ... qui commence à devenir un peu usine à gaz, peut être que ...


    Donc je veux bien faire un PROC (jamais fais ça d'ailleurs).
    Mais je me dis qu'avant d'ameuter tout l'quartier, j'aimerais bien reproduire cette erreur dans un autre contexte (en gros).

    Une affaire à suivre, mais il doit avoir une explication, en espérant que c'est pas l'arbre qui cache la foret.
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  6. #6
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Points : 1 565
    Points
    1 565
    Par défaut
    Si tu n'arrives pas a reproduire le problème en repartant de zero, il faut faire l'inverse : partir du problème et simplifier tout au maximum petit a petit, en vérifiant a chaque suppression que le problème est toujours là.

    Commence a faire une copie de ta base et de ton code pour ne pas casser tout ce que tu as fait, puis :
    * Fait une page avec uniquement la requete qui pose probleme
    * Supprime toutes les tables, champs et autres qui ne sont pas dans la requete
    * Supprime tout ce qui est inutile dans le code PHP en gardant la meme architecture (POO)
    * Supprime la couche d'abstraction PDO (c'est peut etre un bug de la couche aussi, va savoir ^^)
    * etc...

    Evidemment, ca prend du temps et ce n'est peut être pas ta priorité, mais si tu veux fouiller pour comprendre pourquoi, y a que ca a faire je crois ^^

  7. #7
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Effectivement, c'est tout ça qui va falloir que je fasse pour avoir un minimum d'info avant de fusiller MySQL
    (je déconne).

    N'empêche que j'étais à des années lumières de tout ça, en postant ici j'étais quasi convaincu que c'était le SQL qui n'allait pas.

    En tout cas faut bien voir que c'est quasi une pure coïncidence que je tombe dessus.

    Normalement je ne devais pas mettre ce ORDER BY, c'est ma manie de faire du copier/coller de requêtes déjà existantes, j'ai pas du faire gaffe à l'époque.
    Donc quelque part c'est un mal pour un bien.

    Je vais quand même tenter de "jouer" des 2 cotés :
    D'un coté tenter de reproduire cette erreur dans un contexte le plus neutre possible.
    De l'autre (le site) tenter de voir quel serait le truc le plus perturbateur.

    Si c'est ma classe PDO ... c'est la mer**


    Et oui, je sens que ça va me prendre du temps cette histoire.
    Mais comme on dit ici : "Il faut que je trouve le boute". (-> l'erreur)
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  8. #8
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Bon, j'ai refais d'autres essai, et hier, le café n'était peut être pas assez fort.

    J'ai recréé une Bdd, autres tables (même nom, même structure, même données), et là j'ai pu reproduire la même erreur.
    J'ai aussi réduit la requête au stricte minimum :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT COUNT(*) AS total
        FROM ticket t
        JOIN ticket_status_history tsh ON t.ticket_id = tsh.ticket_id
        WHERE t.ticket_customers_id = 104
        GROUP BY t.ticket_id
        ORDER BY t.ref_ticket DESC

    En faisant des essais bruts de décoffrage (en local toujours) avec 4 requêtes :
    -> requêtes avec mysql_* sur les nouvelles tables (autre site/répertoire)
    -> requêtes avec mysql_* sur les tables de mon projet
    -> requête avec PDO sur les nouvelles tables (autre site/répertoire)
    -> requête avec PDO sur les tables de mon projet

    Les 4 donnent les même erreur si je laisse le ORDER BY
    Les 4 donnent les bons résultats en supprimant le ORDER BY ou en indiquant un autre champ (ticket_status_history) que la table "ticket" (où cette dernière n'est pas logique).

    En appliquant ces requêtes dans PhpMyAdmin, même constat.


    Mais aussi, j'ai créé les mêmes tables avec SQLiteManager (donc une Bdd SQLite), et là, quelque soit la requête, les résultats sont correctes, donc même avec un ORDER BY illogique.

    Une fois exécuté cette requête, si je clique dans "modifier" (le SQL), ça vire automatiquement le ORDER BY quelque peu foireux.
    Donc quelque part l'API détecte bien un problème, et même le corrige.
    SQLite serait il plus intelligent que MySQL ?


    Rien qu'avec, j'en conclus quand même que le code de mon projet ne serait pas en cause, et même la Bdd.
    Ouff ...


    J'ai tendance à dire que c'est MySQL qui déconne un peu, que cette erreur serait un peu déboussolé.
    Mais alors là, à quel niveau ???
    Là ça me dépasse.


    Personnellement, j'ai pas trop envie de m'enquiquiner plus longtemps avec ça, car de toute manière ça part d'une requête qui est foireuse.
    Un ORDER BY s'appliquant sur une mauvaise table au minimum si on enlève le COUNT(*).
    Ou si on laisse le COUNT(*), le ORDER BY ne sert strictement à rien.
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  9. #9
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Points : 1 565
    Points
    1 565
    Par défaut
    déjà tu as pu cerner un peu plus le problème et innocenter ton API ;o)

  10. #10
    Membre régulier
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2010
    Messages
    347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2010
    Messages : 347
    Points : 121
    Points
    121
    Par défaut
    T'as des doublons dans tes réponses à sortir? Si oui, il faut utiliser DISTINCT (bon je pense que tu le savais déjà, mais juste au cas ou )

  11. #11
    Membre expérimenté

    Homme Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 249
    Points : 1 565
    Points
    1 565
    Par défaut
    non, c'est son count(*) qui renvoie 2 au lieu de 3 elements

    mais on pourrait essayer count(distinct table.cle) ^^

  12. #12
    Membre expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Points : 3 947
    Points
    3 947
    Par défaut
    Nom mais, il n'y pas vraiment à se torturer l'esprit à vouloir trouver une solution, la question n'est pas là.

    La solution est toute trouvée et ça depuis le début : Dans mon cas il n'y avais absolument pas à mettre un tri (un ORDER BY).
    Faire un tri sur un champ qui lui même n'est pas renvoyé, c'était absurde.
    De plus, c'était un champ dans la table où il y avait qu'1 seule et unique ligne, ce qui était doublement absurde.

    On peu dire que j'avais commis une erreur de syntaxe, ou du moins une instruction SQL illogique.


    En faite, le truc c'était de faire un petit retour sur un comportement de MySQL qui m'a semblé un peu troublant, voir même un peu fort (l'café).


    En faite, j'aurais plus vu 2 cas suivant cette requête :
    - Soit MySQL juge que cette erreur illogique est anodine, et donc parviendra à retourner un résultat toujours correcte, cohérent.

    - Soit MySQL juge que cette erreur est suffisamment grave (le résultat risque d'être incohérent), et bien dans ce cas retourne une erreur.


    Et bien non, c'est ni l'un ni l'autre, mais à mon sens fait pire, MySQL retourne un résultat incohérent, et ça tout en silence, sans le moindre avertissement.

    Donc la question : Est ce normal qu'une Base De Donnée telle que MySQL ait un comportement comme ça fasse à ce genre d'erreur ?
    Il y a erreur tout de même.
    Pour ma part, c'est pas normal, et j'aurais préféré 100 fois une belle erreur.

    D'ailleurs, un essai a démontré que SQLite était plus robuste, retournait le bon résultat fasse à cette même erreur.


    Tant qu'il s'agit d'une application sans aucun enjeu ça va.
    Mais imaginez un instant que l'on "brasse" de l'argent, et bien 2 n'est pas équivalent de 3, et ça peu représenter un sacré gros paquet selon la quantité "brassée" et le temps avant de trouver l'erreur.
    Pas cool MySQL
    Quoi que, ça dépend à qui profite le crime



    M'enfin, il n'y a pas mort d'homme non plus.
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

Discussions similaires

  1. Distinct, group by et order by
    Par gloubi dans le forum Langage SQL
    Réponses: 8
    Dernier message: 27/11/2006, 16h53
  2. problème count et group by
    Par zulkifli dans le forum Requêtes
    Réponses: 3
    Dernier message: 24/11/2006, 04h53
  3. Requête récalcitrante avec un tri par COUNT sans GROUP BY
    Par Ancalagon77 dans le forum Requêtes
    Réponses: 1
    Dernier message: 05/10/2006, 14h27
  4. [SQL] Jointure,Group BY et ORDER BY COUNT qui marche pas
    Par Stef784ever dans le forum Langage SQL
    Réponses: 8
    Dernier message: 17/08/2005, 12h28
  5. Pb de COUNT et GROUP BY simple mais sans requête imbriquées
    Par vanquish dans le forum Langage SQL
    Réponses: 3
    Dernier message: 22/10/2004, 09h45

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