10
votes

Pourquoi cette requête SQL ne renvoie-t-elle pas des résultats comparant des numéros de points flottants?

J'ai ceci dans une table mySQL:

Entrez la description de l'image ici

ID et bolag_id sont int . LAT et LINGItude sont double .

Si j'utilise la colonne LENDIUDE , aucun résultat n'est renvoyé:

Lngtitude Query: Sélectionnez * à partir de location_forslag où Lngtitude = 13.8461208

Cependant, si j'utilise la colonne lat , il fait les résultats de retour :

DAT Query: Sélectionnez * à partir de location_forslag où lat = 58.3902782

Quel est le problème avec la colonne gnongitude


2 commentaires

Essayez où la gravité entre 13.8461208 et 13.8461209 .


@Benoit fonctionne si je le change à 13.8461207 et 13.8461208


3 Réponses :


4
votes

Les points flottants sont irritants .. ..

 WHERE ABS(lngitude - 13.8461208) < 0.00000005


5 commentaires

Cela fonctionne. C'est donc une coïncidence que cela a fonctionné avec l'autre colonne? Puis-je stocker cela dans un meilleur type de données?


Un type de données Decimal est exact dans les versions MySQL récentes, voir le lien.


Le type de données est bien, le problème est que la signification de «égale» dépend de la demande - dans le monde réel, il n'y a rien de tel. Dans une application SATNAV, l'égalité peut être "à moins de 10 mètres". Pour une base de données de registre foncier "à 0,05 mètre" pourrait être suffisamment bonne. Construire une cuisine, il pourrait être "à 5 mm".


@Wrikken: cela peut empêcher les indices d'être utilisés.


@Ben: bon point. Bien qu'il soit plus court pour écrire mon chemin, votre chemin pourrait utiliser des index et pour être honnête, la requête fonctionnera probablement plus de fois que le code est écrit (ce qui n'est qu'une fois, si cela est fait correctement;))



10
votes

6 commentaires

L'utilisation du SQL entre le mot clé n'est pas mauvais dans ce cas (imo plus lisible).


Que diriez-vous d'utiliser gnond comme 13.8461208? Cela pourrait-il être une solution?


@Lille_skutt: Non, vous devez prendre une décision délibérée quelle précision que vous voulez et vos comparaisons explicitement. La base de données n'a rien à vous aider ici - sauf si vous avez installé certaines extensions SIG.


@Ben Okey, mais je trouve ce joli étrange que vous ne pouvez pas comparer un numéro au même numéro. Quelle est la base de la base de données MySQL peut-elle être au plus? La valeur que je l'envoie sera toujours exactement la même que celle de celle-ci.


@ Ce n'est pas le même numéro. 13.8461208 n'est probablement pas un nombre dyadique (aucune représentation finie dans la base 2) car 1/3 n'est pas un nombre décimal. Lorsqu'un ordinateur traduit ce qui est stocké en format binaire à une représentation décimale pour vous et lorsque vous fournissez cette représentation basée sur 10 à l'ordinateur, laissez-le traduire NI Base 2, il peut y avoir des pertes de précision.


@Benoit je vois. Mais comment puis-je savoir avec certitude ce que cette perte de précision peut être au plus?



0
votes

Convertir le flotteur en décimal pour comparer. J'ai eu le même problème et j'ai résolu comme ceci: xxx

regarde les 3 premières lignes après la clausule. J'espère que cela aide.


0 commentaires