numeric
est exact !
Contrairement à une autre réponse, numeric
n'est pas un type à virgule flottante , mais un type de précision arbitraire tel que défini par la norme SQL. Le stockage est exact . Je cite le manuel :
Le type numeric permet de stocker des nombres avec un très grand nombre de chiffres et d'effectuer des calculs avec précision. Il est particulièrement recommandé de stocker des montants monétaires et d'autres quantités lorsque l'exactitude est requise.
Répondre
Le candidat naturel pour votre question est la fonction trunc()
. Il tronque vers zéro - en gardant essentiellement la partie entière tout en supprimant le reste. Le plus rapide dans un test rapide, mais la différence est insignifiante parmi les meilleurs prétendants.
SELECT * FROM t WHERE amount <> trunc(amount);
floor()
tronque à l'entier inférieur suivant, ce qui fait une différence avec les nombres négatifs :
SELECT * FROM t WHERE amount <> floor(amount);
Si vos nombres correspondent à integer
/ bigint
vous pouvez aussi simplement caster :
SELECT * FROM t WHERE amount <> amount::bigint;
Cela tourne en nombres entiers, contrairement à ce qui précède.
Tester
Testé avec PostgreSQL 9.1.7. Table temporaire avec 10k numeric
nombres avec deux chiffres fractionnaires, environ 1 % ont .00
.
CREATE TEMP TABLE t(amount) AS
SELECT round((random() * generate_series (1,10000))::numeric, 2);
Résultat correct dans mon cas :9890 lignes. Meilleur temps sur 10 runs avec EXPLAIN ANALYZE
.
Erwin 1
SELECT count(*) FROM t WHERE amount <> trunc(amount) -- 43.129 ms
mvp 2 / qqx
SELECT count(*) FROM t WHERE amount != round(amount) -- 43.406 ms
Erwin 3
SELECT count(*) FROM t WHERE amount <> amount::int -- 43.668 ms
mvp 1
SELECT count(*) FROM t WHERE round(amount,2) != round(amount) -- 44.144 ms
Erwin 4
SELECT count(*) FROM t WHERE amount <> amount::bigint -- 44.149 ms
Erwin 2
SELECT count(*) FROM t WHERE amount <> floor(amount) -- 44.918 ms
Vice-président Nandakumar
SELECT count(*) FROM t WHERE amount - floor(amount) > .00 -- 46.640 ms
Généralement toujours vrai dans Postgres 12 (sauf que tout est> 10 fois plus rapide maintenant). Testez avec 100 000 lignes au lieu de 10 000 :
db<>jouez ici