Mysql 5 : Tri sur nombres négatifs

Discussion dans 'Administration d'un site Web' créé par Robinson, 26 Janvier 2008.

  1. Robinson
    Robinson WRInaute passionné
    Inscrit:
    26 Octobre 2005
    Messages:
    1 636
    J'aime reçus:
    0
    Bonjour,

    J'ai un petit problème sur une requête de tri.

    Elle doit trier un résultat d'un petit calcul sur deux colonnes.

    ORDER BY (colonne1 * 5 - colonne2 * 3) DESC

    Ces deux colonnes sont de type UNSIGNED.
    Problème, il considère les nombres négatifs comme supérieurs...

    Avec mysql 4, cela fonctionnait sans problème. Avez-vous une solution svp ? Merci.
     
  2. jcaron
    jcaron WRInaute accro
    Inscrit:
    13 Février 2004
    Messages:
    2 579
    J'aime reçus:
    0
    Au moins solutions:
    - convertir en signed d'abord (cast(colonne1 as signed)..)
    - ajouter une grande valeur (supérieure à la valeur absolue de la différence la plus petite) *avant* de soustraire, pour que le résultat reste positif (par exemple 10000 + colonne1*5 - colonne2*3)

    Il doit y en avoir d'autres...

    Jacques.
     
  3. Robinson
    Robinson WRInaute passionné
    Inscrit:
    26 Octobre 2005
    Messages:
    1 636
    J'aime reçus:
    0
    Merci, je vais utiliser la seconde solution :)
     
  4. FlorentP
    FlorentP WRInaute discret
    Inscrit:
    25 Juin 2005
    Messages:
    131
    J'aime reçus:
    0
    Ou reporter le bug a mysql :d
     
  5. ecocentric
    ecocentric WRInaute accro
    Inscrit:
    10 Février 2004
    Messages:
    2 653
    J'aime reçus:
    0
    idée bête: tu as essayé de mettre un alias dans le SELECT et d'utiliser l'alias dans l'ORDER BY ?
     
  6. jcaron
    jcaron WRInaute accro
    Inscrit:
    13 Février 2004
    Messages:
    2 579
    J'aime reçus:
    0
    Je ne vois pas où est le bug, si on travaille avec des entiers non signés, et que le résultat d'une opération est négatif, forcément ça donne des choses pas très prévisibles, rien de plus normal.

    Jacques.
     
  7. Robinson
    Robinson WRInaute passionné
    Inscrit:
    26 Octobre 2005
    Messages:
    1 636
    J'aime reçus:
    0
    Oui et c'est la même chose.

    jcaron, pourquoi cela fonctionnait dans les versions mysql précédentes ?
    Pas besoin de me répondre, je pense avoir une idée, comme php, les deux se veulent de plus en plus professionnels et donc de plus en plus tatillons et respectueux des normes de développement ^^
     
  8. FlorentP
    FlorentP WRInaute discret
    Inscrit:
    25 Juin 2005
    Messages:
    131
    J'aime reçus:
    0
    Ce n'est pas parceque les chiffres qu'il manipule sont non signés que le résultat doit l'être...
    C'est comme si tu disais que mysql devait te retourner un résultat entre 0 et 255 si on faisait des opérations à partir d'un tinyint. Un tinyint multiplié par un autre, ya pas de raison qu'il reste borné dans un tinyint. Idem pour des opérations avec des unsigned.
     
  9. jcaron
    jcaron WRInaute accro
    Inscrit:
    13 Février 2004
    Messages:
    2 579
    J'aime reçus:
    0
    Dans tous les langages que je connais, y compris SQL, le résultat d'une opération sur deux valeurs d'un type X est presque systématiquement (voire même tout le temps?) dans le même type X. C'est totalement volontaire, et ce n'est pas un bug, même s'il y a au moins un bug report par mois (refermé aussi vite) comme quoi postgresql est buggé parce qu'il dit que (par exemple) 1 / 2 * 2 = 0. Si tu veux obtenir le "bon" résultat, il faut passer par des floats, mais tu ne veux pas non plus qu'il passe sur des floats pour un oui ou pour un non alors que toi tu voulais qu'il reste sur des entiers... C'est un choix arbitraire, mais c'est comme ça.

    D'ailleurs visiblement, ils doivent considérer que le comportement précédent est un bug, et qu'ils l'ont corrigé, il y a un moyen d'avoir l'ancien comportement:

    "Si vous rencontrez un problème avec les colonnes UNSIGNED dans vos anciennes applications MySQL lorsque vous effectuez le port sous la version 4.0 de MySQL , vous pouvez utiliser l'option --sql-mode=NO_UNSIGNED_SUBTRACTION lorsque vous lancez mysqld. Notez cependant qu'aussi longtemps que vous employez ceci, vous ne serez pas capable d'utiliser efficacement les colonnes de type UNSIGNED BIGINT."

    (from http://dev.mysql.com/doc/refman/5.0/fr/ ... tions.html)

    Je n'ai pas de serveur mysql sous la main, mais dans postgresql c'est nettement plus clair (mais smallint est sur 16 bits et pas 8 bits, et il n'y a pas de signed/unsigned):

    Code:
    # select 10000::smallint * 10000::smallint;
    ERROR:  smallint out of range
    
    # \do
                                                                                  Liste des opérateurs
       Schéma   | Nom  |    Type de l'arg. gauche    |    Type de l'arg. droit     |      Type du résultat       |                           Description                            
    ------------+------+-----------------------------+-----------------------------+-----------------------------+------------------------------------------------------------------
    [...]
     pg_catalog | *    | smallint                    | smallint                    | smallint                    | multiply
    
    Jacques.
     
  10. FlorentP
    FlorentP WRInaute discret
    Inscrit:
    25 Juin 2005
    Messages:
    131
    J'aime reçus:
    0
    Bon apparement la solution au probleme c'est pas de reporter le changement de comportement a mysql mais de mettre l'option --sql-mode=NO_UNSIGNED_SUBTRACTION...

    Pour ce qui est du résultat qui est toujours de type x sur une opération entre deux valeurs de type x : en C, si tu fais
    printf("%d",r, unsigned int - unsigned int);
    tu peux récupérer des valeures négatives sur ta valeure de retour.
    Ce type de traitement doit être assez spécifique à certains langages, et je trouve pas ça super logique que ça fonctionne comme ça par défaut
     
  11. jcaron
    jcaron WRInaute accro
    Inscrit:
    13 Février 2004
    Messages:
    2 579
    J'aime reçus:
    0
    Parce que %d indique que la valeur est à condidérer comme un signed int. Tu devrais normalement utiliser %u (comme au final la représentation binaire reste la même, et que C ne fait pas d'erreur en cas d'overflow, tu retombes sur tes pattes).

    Essaie plutôt ça:

    Code:
    unsigned a,b;
    a=10;
    b=20
    if (a-b < 0)
    {
             printf("negatif\n");
    }
    else
    {
            printf("positif\n");
    }
    
    C'est comme ça en C comme en SQL. Je pense que c'est vrai dans beaucoup de langages fortement typés...

    Jacques.
     
  12. Robinson
    Robinson WRInaute passionné
    Inscrit:
    26 Octobre 2005
    Messages:
    1 636
    J'aime reçus:
    0
    Oui, c'est ainsi dans plein de langages, je l'avais déjà vu il y a quelques années (peut-être bien avec Access ou en C, me souviens pu).

    Mon ptit BTS commence à remonter à quelques années, me fait vieux :'(
    Et cette rigueur de développement, je l'avais un peu zappée avec le php et mysql ^^
     
Chargement...
Similar Threads - Mysql Tri nombres Forum Date
Requête Mysql avec des string Développement d'un site Web ou d'une appli mobile 6 Février 2018
Mysql - un Group by non trié sur plusieurs tables ... Développement d'un site Web ou d'une appli mobile 13 Mars 2013
Trier les résultats - mysql Développement d'un site Web ou d'une appli mobile 7 Mai 2012
[MYSQL] Tri par date Développement d'un site Web ou d'une appli mobile 7 Septembre 2011
[MySQL] addslashes et stripslashes Développement d'un site Web ou d'une appli mobile 9 Août 2011
Optimisation d'un tri Mysql Développement d'un site Web ou d'une appli mobile 23 Juillet 2011
La notion de Trigger ... ca existe dans mysql ? Développement d'un site Web ou d'une appli mobile 28 Mai 2011
[mysql] trier les résultats d'une requête selon une table non liée à la requête Développement d'un site Web ou d'une appli mobile 15 Avril 2011
MySQL : comment grouper les entrées puis les trier ? Développement d'un site Web ou d'une appli mobile 21 Mars 2011
addslashes, mysql_real_escape_string, htmlentities ? Développement d'un site Web ou d'une appli mobile 28 Janvier 2011
Requête mysql : Tri complexe des commentaires par votes Développement d'un site Web ou d'une appli mobile 13 Octobre 2010
MySQL, jointures multiples, WHERE et psychiatrie Développement d'un site Web ou d'une appli mobile 27 Juillet 2010
question concernant mysql_real_escape_string insertion dans une table Développement d'un site Web ou d'une appli mobile 21 Octobre 2009
Tri sur champ Date Mysql Développement d'un site Web ou d'une appli mobile 8 Septembre 2009
mysql_real_escape_string() suffisant contre les injections SQL? Développement d'un site Web ou d'une appli mobile 16 Mai 2009
Enregistrement en bd et mysql_real_escape_string() Développement d'un site Web ou d'une appli mobile 12 Septembre 2008
[PHP/MySQL] Problème dans le tri Développement d'un site Web ou d'une appli mobile 26 Août 2008
trie alphabetique russe mysql / php Développement d'un site Web ou d'une appli mobile 22 Novembre 2007
tri (mysql ou php) Développement d'un site Web ou d'une appli mobile 15 Novembre 2007
MySQL - Tri d'une table par occurences d'une valeur Développement d'un site Web ou d'une appli mobile 25 Février 2007