Visualizzazione dei risultati da 1 a 5 su 5
  1. #1

    [MySQL] SUM restituisce valore errato

    Ciao,
    la funzione SUM di MySQL si comporta in modo strano.
    Ho la seguente tabella:

    codice:
    +----+-------+----------+---------------+
    | id | price | currency |   category    |
    +----+-------+----------+---------------+
    |  1 |   15  |    USD   | abbigliamento |
    +----+-------+----------+---------------+
    |  2 |   25  |    EUR   |   gioielli    |
    +----+-------+----------+---------------+
    |  3 |   28  |    USD   | abbigliamento |
    +----+-------+----------+---------------+
    |  4 |   48  |    GBP   |   gioielli    |
    +----+-------+----------+---------------+
    |  5 |   11  |    GBP   |     casa      |
    +----+-------+----------+---------------+
    |  6 |   35  |    GBP   |     casa      |
    +----+-------+----------+---------------+
    |  7 |  191  |    USD   |     casa      |
    +----+-------+----------+---------------+
    |  8 | 48.45 |    GBP   |   gioielli    |
    +----+-------+----------+---------------+
    |  9 |  12.5 |    EUR   |     casa      |
    +----+-------+----------+---------------+
    | 10 |  25.2 |    EUR   | abbigliamento |
    +----+-------+----------+---------------+
    
    
    La cui struttura è:
    
         id INT(10) UNSIGNED NOT NULL auto_increment,
         price float unsigned NOT NULL default '0',
         currency VARCHAR(3) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '',
         category VARCHAR(50) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL default '',
         PRIMARY KEY(id)
    Per calcolare la somma dei valori della colonna price lancio la semplice query:
    $query = "SELECT SUM(price) FROM tbl";

    La somma effettiva è 429.15, ma MySQL restituisce 429.15000152588
    La stessa cosa avviene con la funzione AVG().
    La media effettiva dei valori del campo price è 429.15 / 10 = 42.915, invece MySQL restituisce 42.915000152588

    Cosa c'entra quel 0.000000152588 che viene aggiunto ai valori reali?
    Perché questa discrepanza?

    Sto usando questa piccola tabella di test per verificare errori più significativi che avvenivano su tabelle più grandi con query molto più complesse.
    (Uso la versione MySQL 4.1.20)
    Emanuele DG
    <?php echo "Proverbio zen(d): vivi ogni giorno come se fosse il ".date('d M Y', time()); ?>
    Intellectual property

  2. #2
    il problema e' del float ed e' legato anche al OS e all'hardare usato.

    per le valute usa decimal

    Il silenzio è spesso la cosa migliore. Pensa ... è gratis.

  3. #3
    Originariamente inviato da piero.mac
    il problema e' del float ed e' legato anche al OS e all'hardare usato.

    per le valute usa decimal
    Grazie,
    sono contento che questa volta l'errore sia da far risalire al mondo delle macchine perché vuol dire che la mia logica ha ragione.
    Stranissimo, sembra che l'errore si propaghi su tutte le funzioni, aggregate e non; ho provato con MIN, MAX etc e il risultato è lo stesso, l'errore c'è sempre.

    Ho provato a lanciare una query di controllo:

    $query = "SELECT SUM(price), COUNT(*), SUM(price)/COUNT(*), AVG(price) FROM tbl";

    Risultato:
    codice:
    +-----------------+----------+----------------------+------------------+
    |    SUM(price)   | COUNT(*) |  SUM(price)/COUNT(*) |    AVG(price)    |
    +-----------------+----------+----------------------+------------------+
    | 429.15000152588 |    10    |    42.915000152588   |  42.915000152588 |
    +-----------------+----------+----------------------+------------------+
    Sistema operativo:
    • Apache/2.0.52 (CentOS)
    • PHP 4.3.9
    • MySQL 4.1.20


    Sto cercando su http://dev.mysql.com per vedere se esiste un bug segnalato alla MySQL AB per questa casistica.
    Comunque poi ho modificato il tipo del campo price da FLOAT a DECIMAL(10,2).
    La stessa query di sopra sembra lavorare bene:

    codice:
    +--------------+------------+----------------------+------------------+
    |  SUM(price)  |  COUNT(*)  |  SUM(price)/COUNT(*) |    AVG(price)    |
    +--------------+------------+----------------------+------------------+
    |   429.15     |     10     |       42.9150        |     42.915000    |
    +--------------+------------+----------------------+------------------+
    L'unico neo è che specificano il numero fino alla quarta cifra decimale. Almeno però è un numero corretto.
    Emanuele DG
    <?php echo "Proverbio zen(d): vivi ogni giorno come se fosse il ".date('d M Y', time()); ?>
    Intellectual property

  4. #4

  5. #5
    Grazie Piero sei sempre un grande,
    con ritardo ti faccio gli auguri per ieri!

    Per quanto riguarda i primi due link, non mi sarei mai aspettato di trovare quelle linee guida basilari sotto il link "community", il che mi fa pensare ancor di più che il sito www.mysql.org sia mal strutturato come molti affermavano prima di me.

    Dekuji moc, ahoj a nashledanou!
    Emanuele DG
    <?php echo "Proverbio zen(d): vivi ogni giorno come se fosse il ".date('d M Y', time()); ?>
    Intellectual property

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.