Vous n'êtes pas identifié(e).
Bonjour,
Je suis en PostgreSQL 8.4.3 sous RedHat.
J'observe un comportement curieux quand je fais la somme sur une colonne de type REAL (nombre à virgule flottante sur 4 octets).
En effet, si je fais la requête suivante :
SELECT SUM(macolonne1) AS total_colonne1 FROM matable
J'obtiens le total suivant : 275375
Si je décompose ensuite selon une seconde colonne, par la requête suivante :
SELECT macolonne2, SUM(macolonne1) AS total_colonne1 FROM matable GROUP BY macolonne2
J'obtiens le résultat suivant :
macolonne2 total_colonne1
0 54754,8
1 54601,1
2 55598,3
3 55248
4 55178
dont le total fait 275380,2.
Enfin, si j'exécute la requête suivante, en typant ma colonne explicitement :
SELECT SUM(macolonne1::float) AS total_colonne1 FROM matable
J'obtiens un total de 275381,66...
Quand j'exporte toutes mes lignes dans un outil permettant de faire la somme sur la colonne 1 (logiciel R), le total que m'affiche cet outil est 275381,66.
Bref, je suis surpris d'observer de tels écarts. A quoi cela peut-il être dû ?
Et surtout, que dois-je faire dans mes différentes requêtes qui utilisent des sommes (ou autres fonctions d'agrégations) pour être certain que mes totaux soient le plus juste possible ? Faut-il systématiquement caster explicitement ?
Merci de votre aide,
ced
Dernière modification par ced (07/06/2010 12:20:04)
Hors ligne
Cela est du à des erreurs d'arrondis (les float et double utilisent une notation mantisse/exposant). Si vous voulez travailler avec des résultats exacts, utilisez les formats numeric. Sachez par contre qu'ils sont plus lents.
Pour reprendre :
SELECT SUM(macolonne1) AS total_colonne1 FROM matable : vous faites des sommes de 'real', c'est à dire de nombres simple précision.
SELECT macolonne2, SUM(macolonne1) AS total_colonne1 FROM matable GROUP BY macolonne2, vous faites des sommes de real, recevez un résultat arrondi, que vous sommez ensuite à la main.
SELECT SUM(macolonne1::float) AS total_colonne1 FROM matable : vous convertissez vos simple précision en double précision, puis faites une somme double précision.
Marc.
Hors ligne
Merci pour ces éléments de réponse.
La première requête me laisse tout de même perplexe : pourquoi une somme sur un nombre stocké en real entraîne un tel écart de total au final (plusieurs unités) ?
Quand on regarde la documentation de PostgreSQL, il est précisé que le type real a une précision d'au moins 6 chiffres décimaux.
Sachant que ma table contient 250000 lignes, je devrais avoir un erreur de l'ordre de 0,25 et pas de plusieurs unités ?
ced
Dernière modification par ced (07/06/2010 15:31:32)
Hors ligne
La précision est de 6 chiffres sur le real. En tout, pas après la virgule. C'est la taille de la «mantisse».
Marc.
Hors ligne